/*
 * Copyright (c) 2009 - 2012 Deutsches Elektronen-Synchroton,
 * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program (see the file COPYING.LIB for more
 * details); if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.dcache.xdr;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.logging.Logger;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.WriteResult;
import org.glassfish.grizzly.filterchain.FilterChainContext;

public class GrizzlyXdrTransport implements XdrTransport {

    private final FilterChainContext _context;
    private final Connection<InetSocketAddress> _connection;
    private final ReplyQueue<Integer, RpcReply> _replyQueue;

    private final static Logger _log = Logger.getLogger(GrizzlyXdrTransport.class.getName());

    public GrizzlyXdrTransport(FilterChainContext context, ReplyQueue<Integer, RpcReply> replyQueue) {
        _context = context;
        _connection = context.getConnection();
        _replyQueue = replyQueue;
    }

    public GrizzlyXdrTransport(FilterChainContext context) {
        this(context, null);
    }

    @Override
    public void send(Xdr xdr) throws IOException {
        Buffer buffer = xdr.asBuffer();
        buffer.allowBufferDispose(true);

        // pass destination address to handle UDP connections as well
        _context.write(_context.getAddress(), buffer, null);
    }

    @Override
    public InetSocketAddress getLocalSocketAddress() {
        return (InetSocketAddress)_context.getConnection().getLocalAddress();
    }

    @Override
    public InetSocketAddress getRemoteSocketAddress() {
        return (InetSocketAddress)_context.getAddress();
    }

    @Override
    public ReplyQueue<Integer, RpcReply> getReplyQueue() {
        return _replyQueue;
    }

    @Override
    public XdrTransport getPeerTransport() {
        return new ClientTransport(_connection, getReplyQueue());
    }

    @Override
    public String toString() {
        return getRemoteSocketAddress() + " <=> " + getLocalSocketAddress();
    }
}

@@ -1092,23 +1092,16 @@
 y.Co
-mpletionHandler
+nnection
 ;%0Aim
@@ -1123,34 +1123,107 @@
 ish.grizzly.
-Connection
+asyncqueue.PushBackContext;%0Aimport org.glassfish.grizzly.asyncqueue.PushBackHandler
 ;%0Aimport org
@@ -1245,19 +1245,34 @@
 zly.
-WriteResult
+asyncqueue.WritableMessage
 ;%0Aim
@@ -2243,24 +2243,52 @@
 buffer, null
+, new RetryPushBackHandler()
 );%0A    %7D%0A%0A  
@@ -2854,24 +2854,24 @@
 oString() %7B%0A
-
         retu
@@ -2940,11 +2940,412 @@
 );%0A    %7D
+%0A%0A    private static class RetryPushBackHandler implements PushBackHandler %7B%0A%0A        @Override%0A        public void onAccept(Connection connection, WritableMessage message) %7B%0A            // NOP%0A        %7D%0A%0A        @Override%0A        public void onPushBack(Connection connection, WritableMessage message, PushBackContext pushBackContext) %7B%0A            pushBackContext.retryWhenPossible();%0A        %7D%0A    %7D
 %0A%7D%0A

add PushBack handler