/*
* Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.grizzly;
import java.io.IOException;
import java.util.concurrent.Future;
import org.glassfish.grizzly.asyncqueue.MessageCloner;
import org.glassfish.grizzly.asyncqueue.WritableMessage;
Implementations of this interface are able to write data from a Buffer
to Connection
. There are two basic Writer implementations in Grizzly: AsyncQueueWriter
, TemporarySelectorWriter
. Author: Alexey Stashok Type parameters: - <L> – the writer address type
/**
* Implementations of this interface are able to write data from a {@link Buffer} to {@link Connection}.
*
* There are two basic Writer implementations in Grizzly: {@link org.glassfish.grizzly.asyncqueue.AsyncQueueWriter},
* {@link org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorWriter}.
*
* @param <L> the writer address type
*
* @author Alexey Stashok
*/
@SuppressWarnings("deprecation")
public interface Writer<L> {
Method writes the WritableMessage
. Params: - connection – the
Connection
to write to - message – the
WritableMessage
, from which the data will be written
Throws: - IOException – not thrown
Returns: Future
, using which it's possible to check the result
/**
* Method writes the {@link WritableMessage}.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param message the {@link WritableMessage}, from which the data will be written
* @return {@link Future}, using which it's possible to check the result
* @throws java.io.IOException not thrown
*/
GrizzlyFuture<WriteResult<WritableMessage, L>> write(Connection<L> connection, WritableMessage message) throws IOException;
Method writes the WritableMessage
. Params: - connection – the
Connection
to write to - message – the
WritableMessage
, from which the data will be written - completionHandler –
CompletionHandler
, which will get notified, when write will be completed
/**
* Method writes the {@link WritableMessage}.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param message the {@link WritableMessage}, from which the data will be written
* @param completionHandler {@link org.glassfish.grizzly.CompletionHandler}, which will get notified, when write will be
* completed
*/
void write(Connection<L> connection, WritableMessage message, CompletionHandler<WriteResult<WritableMessage, L>> completionHandler);
Method writes the WritableMessage
to the specific address. Params: - connection – the
Connection
to write to - dstAddress – the destination address the
WritableMessage
will be sent to - message – the
WritableMessage
, from which the data will be written
Returns: Future
, using which it's possible to check the result
/**
* Method writes the {@link WritableMessage} to the specific address.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param dstAddress the destination address the {@link WritableMessage} will be sent to
* @param message the {@link WritableMessage}, from which the data will be written
* @return {@link Future}, using which it's possible to check the result
*/
GrizzlyFuture<WriteResult<WritableMessage, L>> write(Connection<L> connection, L dstAddress, WritableMessage message);
Method writes the WritableMessage
to the specific address. Params: - connection – the
Connection
to write to - dstAddress – the destination address the
WritableMessage
will be sent to - message – the
WritableMessage
, from which the data will be written - completionHandler –
CompletionHandler
, which will get notified, when write will be completed
/**
* Method writes the {@link WritableMessage} to the specific address.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param dstAddress the destination address the {@link WritableMessage} will be sent to
* @param message the {@link WritableMessage}, from which the data will be written
* @param completionHandler {@link org.glassfish.grizzly.CompletionHandler}, which will get notified, when write will be
* completed
*/
void write(Connection<L> connection, L dstAddress, WritableMessage message, CompletionHandler<WriteResult<WritableMessage, L>> completionHandler);
Method writes the WritableMessage
to the specific address. Params: - connection – the
Connection
to write to - dstAddress – the destination address the
WritableMessage
will be sent to - message – the
WritableMessage
, from which the data will be written - completionHandler –
CompletionHandler
, which will get notified, when write will be completed - pushBackHandler –
PushBackHandler
, which will be notified if message was accepted by transport write queue or refused
Deprecated: push back logic is deprecated
/**
* Method writes the {@link WritableMessage} to the specific address.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param dstAddress the destination address the {@link WritableMessage} will be sent to
* @param message the {@link WritableMessage}, from which the data will be written
* @param completionHandler {@link org.glassfish.grizzly.CompletionHandler}, which will get notified, when write will be
* completed
* @param pushBackHandler {@link org.glassfish.grizzly.asyncqueue.PushBackHandler}, which will be notified if message
* was accepted by transport write queue or refused
* @deprecated push back logic is deprecated
*/
@Deprecated
void write(Connection<L> connection, L dstAddress, WritableMessage message, CompletionHandler<WriteResult<WritableMessage, L>> completionHandler,
org.glassfish.grizzly.asyncqueue.PushBackHandler pushBackHandler);
Method writes the WritableMessage
to the specific address. Params: - connection – the
Connection
to write to - dstAddress – the destination address the
WritableMessage
will be sent to - message – the
WritableMessage
, from which the data will be written - completionHandler –
CompletionHandler
, which will get notified, when write will be completed - messageCloner – the
MessageCloner
, which will be able to clone the message in case it can't be completely written in the current thread.
/**
* Method writes the {@link WritableMessage} to the specific address.
*
*
* @param connection the {@link org.glassfish.grizzly.Connection} to write to
* @param dstAddress the destination address the {@link WritableMessage} will be sent to
* @param message the {@link WritableMessage}, from which the data will be written
* @param completionHandler {@link org.glassfish.grizzly.CompletionHandler}, which will get notified, when write will be
* completed
* @param messageCloner the {@link MessageCloner}, which will be able to clone the message in case it can't be
* completely written in the current thread.
*/
void write(Connection<L> connection, L dstAddress, WritableMessage message, CompletionHandler<WriteResult<WritableMessage, L>> completionHandler,
MessageCloner<WritableMessage> messageCloner);
Return true
if the connection has not exceeded it's maximum size in bytes of pending writes, otherwise
false
.
Params: - connection – the
Connection
to test whether or not the specified number of bytes can be written to.
Returns: true
if the connection has not exceeded it's maximum size in bytes of pending writes, otherwise
false
Since: 2.3
/**
* Return <code>true</code> if the connection has not exceeded it's maximum size in bytes of pending writes, otherwise
* <code>false</code>.
*
* @param connection the {@link Connection} to test whether or not the specified number of bytes can be written to.
* @return <code>true</code> if the connection has not exceeded it's maximum size in bytes of pending writes, otherwise
* <code>false</code>
*
* @since 2.3
*/
boolean canWrite(final Connection<L> connection);
Registers WriteHandler
, which will be notified ones at least one byte can be written. This method call is equivalent to call notifyWritePossible(connection, writeHandler, 1); Note: using this method from different threads simultaneously may lead to quick situation changes, so at time WriteHandler
is called - the queue may become busy again. Params: - connection –
Connection
- writeHandler –
WriteHandler
to be notified.
Since: 2.3
/**
* Registers {@link WriteHandler}, which will be notified ones at least one byte can be written.
*
* This method call is equivalent to call notifyWritePossible(connection, writeHandler, <tt>1</tt>);
*
* Note: using this method from different threads simultaneously may lead to quick situation changes, so at time
* {@link WriteHandler} is called - the queue may become busy again.
*
* @param connection {@link Connection}
* @param writeHandler {@link WriteHandler} to be notified.
*
* @since 2.3
*/
void notifyWritePossible(final Connection<L> connection, final WriteHandler writeHandler);
Write reentrants counter
/**
* Write reentrants counter
*/
final class Reentrant {
private static final ThreadLocal<Reentrant> REENTRANTS_COUNTER = new ThreadLocal<Reentrant>() {
@Override
protected Reentrant initialValue() {
return new Reentrant();
}
};
private static final int maxWriteReentrants = Integer.getInteger("org.glassfish.grizzly.Writer.max-write-reentrants", 10);
Returns the maximum number of write() method reentrants a thread is allowed to made. This is related to possible
write()->onComplete()->write()->... chain, which may grow infinitely and cause StackOverflow. Using
maxWriteReentrants value it's possible to limit such a chain.
Returns: the maximum number of write() method reentrants a thread is allowed to make.
/**
* Returns the maximum number of write() method reentrants a thread is allowed to made. This is related to possible
* write()->onComplete()->write()->... chain, which may grow infinitely and cause StackOverflow. Using
* maxWriteReentrants value it's possible to limit such a chain.
*
* @return the maximum number of write() method reentrants a thread is allowed to make.
*/
public static int getMaxReentrants() {
return maxWriteReentrants;
}
Returns the current write reentrants counter. Might be useful, if developer wants to use custom notification mechanism, based on on Writer.canWrite(Connection<L>)
and various write methods. Returns: current reentrants counter
/**
* Returns the current write reentrants counter. Might be useful, if developer wants to use custom notification
* mechanism, based on on {@link #canWrite(org.glassfish.grizzly.Connection)} and various write methods.
*
* @return current reentrants counter
*/
public static Reentrant getWriteReentrant() {
// ThreadLocal otherwise
return REENTRANTS_COUNTER.get();
}
private int counter;
Returns the value of the reentrants counter for the current thread.
/**
* Returns the value of the reentrants counter for the current thread.
*/
public int get() {
return counter;
}
Increments the reentrants counter by one.
Returns: true if the counter (after incrementing) didn't reach getMaxReentrants()
limit, or false otherwise.
/**
* Increments the reentrants counter by one.
*
* @return <tt>true</tt> if the counter (after incrementing) didn't reach {@link #getMaxReentrants()} limit, or
* <tt>false</tt> otherwise.
*/
public boolean inc() {
return ++counter <= maxWriteReentrants;
}
Decrements the reentrants counter by one.
Returns: true if the counter (after decrementing) didn't reach getMaxReentrants()
limit, or false otherwise.
/**
* Decrements the reentrants counter by one.
*
* @return <tt>true</tt> if the counter (after decrementing) didn't reach {@link #getMaxReentrants()} limit, or
* <tt>false</tt> otherwise.
*/
public boolean dec() {
return --counter <= maxWriteReentrants;
}
Returns true, if max number of write->completion-handler reentrants has been reached for the passed Reentrant
object, and next write will happen in the separate thread. Returns: true, if max number of write->completion-handler reentrants has been reached for the passed Reentrant
object, and next write will happen in the separate thread.
/**
* Returns <tt>true</tt>, if max number of write->completion-handler reentrants has been reached for the passed
* {@link Reentrant} object, and next write will happen in the separate thread.
*
* @return <tt>true</tt>, if max number of write->completion-handler reentrants has been reached for the passed
* {@link Reentrant} object, and next write will happen in the separate thread.
*/
public boolean isMaxReentrantsReached() {
return get() >= getMaxReentrants();
}
}
}