Package com.martiansoftware.nailgun
Class NGInputStream
- java.lang.Object
-
- java.io.InputStream
-
- java.io.FilterInputStream
-
- com.martiansoftware.nailgun.NGInputStream
-
- All Implemented Interfaces:
java.io.Closeable,java.lang.AutoCloseable
public class NGInputStream extends java.io.FilterInputStream implements java.io.CloseableA FilterInputStream that is able to read the chunked stdin stream from a NailGun client.
-
-
Field Summary
Fields Modifier and Type Field Description private booleanclientConnectedprivate java.util.Set<NGClientListener>clientListenersprivate java.io.DataInputStreamdinprivate booleaneofprivate java.util.Set<NGHeartbeatListener>heartbeatListenersprivate static java.util.logging.LoggerLOGprivate byte[]oneByteBufferprivate java.util.concurrent.ExecutorServiceorchestratorExecutorprivate java.io.DataOutputStreamoutprivate java.util.concurrent.ExecutorServicereadExecutorprivate intremainingprivate booleanstartedprivate java.io.InputStreamstdinprivate static longTERMINATION_TIMEOUT_MS
-
Constructor Summary
Constructors Constructor Description NGInputStream(java.io.DataInputStream in, java.io.DataOutputStream out, int heartbeatTimeoutMillis)Creates a new NGInputStream wrapping the specified InputStream.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddClientListener(NGClientListener listener)Registers a new NGClientListener to be called on client disconnection or calls the listeners clientDisconnected method if the client has already disconnected to avoid races.voidaddHeartbeatListener(NGHeartbeatListener listener)intavailable()voidclose()Cancel the thread reading from the NailGun client and close underlying input streambooleanisClientConnected()booleanmarkSupported()private voidnotifyClientListeners()Calls clientDisconnected method on all registered NGClientListeners.intread()intread(byte[] b)intread(byte[] b, int offset, int length)private voidreadChunk()Reads a NailGun chunk header from the underlying InputStream.private java.io.InputStreamreadPayload(java.io.InputStream in, int len)Reads a NailGun chunk payload fromFilterInputStream.inand returns an InputStream that reads from that chunk.voidremoveAllClientListeners()Do not notify anymore about client disconnectsvoidremoveClientListener(NGClientListener listener)voidremoveHeartbeatListener(NGHeartbeatListener listener)private voidsendSendInput()private voidsetClientDisconnected()Notify threads waiting in read() on either EOF chunk read or client disconnection.private voidsetEof()Notify threads waiting in read() on either EOF chunk read or client disconnection.private static voidterminateExecutor(java.util.concurrent.ExecutorService service, java.lang.String which)
-
-
-
Field Detail
-
LOG
private static final java.util.logging.Logger LOG
-
orchestratorExecutor
private final java.util.concurrent.ExecutorService orchestratorExecutor
-
readExecutor
private final java.util.concurrent.ExecutorService readExecutor
-
din
private final java.io.DataInputStream din
-
stdin
private java.io.InputStream stdin
-
eof
private boolean eof
-
clientConnected
private boolean clientConnected
-
remaining
private int remaining
-
oneByteBuffer
private byte[] oneByteBuffer
-
out
private final java.io.DataOutputStream out
-
started
private boolean started
-
clientListeners
private final java.util.Set<NGClientListener> clientListeners
-
heartbeatListeners
private final java.util.Set<NGHeartbeatListener> heartbeatListeners
-
TERMINATION_TIMEOUT_MS
private static final long TERMINATION_TIMEOUT_MS
- See Also:
- Constant Field Values
-
-
Constructor Detail
-
NGInputStream
public NGInputStream(java.io.DataInputStream in, java.io.DataOutputStream out, int heartbeatTimeoutMillis)Creates a new NGInputStream wrapping the specified InputStream. Also sets up a timer to periodically consume heartbeats sent from the client and call registered NGClientListeners if a client disconnection is detected.- Parameters:
in- the InputStream to wrapout- the OutputStream to which SENDINPUT chunks should be sentheartbeatTimeoutMillis- the interval between heartbeats before considering the client disconnected
-
-
Method Detail
-
notifyClientListeners
private void notifyClientListeners()
Calls clientDisconnected method on all registered NGClientListeners.
-
close
public void close() throws java.io.IOExceptionCancel the thread reading from the NailGun client and close underlying input stream- Specified by:
closein interfacejava.lang.AutoCloseable- Specified by:
closein interfacejava.io.Closeable- Overrides:
closein classjava.io.FilterInputStream- Throws:
java.io.IOException
-
terminateExecutor
private static void terminateExecutor(java.util.concurrent.ExecutorService service, java.lang.String which)
-
readPayload
private java.io.InputStream readPayload(java.io.InputStream in, int len) throws java.io.IOExceptionReads a NailGun chunk payload fromFilterInputStream.inand returns an InputStream that reads from that chunk.- Parameters:
in- the InputStream to read the chunk payload from.len- the size of the payload chunk read from the chunkHeader.- Returns:
- an InputStream containing the read data.
- Throws:
java.io.IOException- if thrown by the underlying InputStreamjava.io.EOFException- if EOF is reached by underlying stream before the payload has been read.
-
readChunk
private void readChunk() throws java.io.IOExceptionReads a NailGun chunk header from the underlying InputStream.- Throws:
java.io.EOFException- if underlying stream / socket is closed which happens on client disconnectionjava.io.IOException- if thrown by the underlying InputStream, or if an unexpected NailGun chunk type is encountered.
-
setEof
private void setEof()
Notify threads waiting in read() on either EOF chunk read or client disconnection.
-
setClientDisconnected
private void setClientDisconnected()
Notify threads waiting in read() on either EOF chunk read or client disconnection.
-
available
public int available() throws java.io.IOException- Overrides:
availablein classjava.io.FilterInputStream- Throws:
java.io.IOException- See Also:
InputStream.available()
-
markSupported
public boolean markSupported()
- Overrides:
markSupportedin classjava.io.FilterInputStream- See Also:
InputStream.markSupported()
-
read
public int read() throws java.io.IOException- Overrides:
readin classjava.io.FilterInputStream- Throws:
java.io.IOException- See Also:
InputStream.read()
-
read
public int read(byte[] b) throws java.io.IOException- Overrides:
readin classjava.io.FilterInputStream- Throws:
java.io.IOException- See Also:
InputStream.read(byte[])
-
read
public int read(byte[] b, int offset, int length) throws java.io.IOException- Overrides:
readin classjava.io.FilterInputStream- Throws:
java.io.IOException- See Also:
InputStream.read(byte[], int, int)
-
sendSendInput
private void sendSendInput() throws java.io.IOException- Throws:
java.io.IOException
-
isClientConnected
public boolean isClientConnected()
- Returns:
- true if interval since last read is less than heartbeat timeout interval.
-
addClientListener
public void addClientListener(NGClientListener listener)
Registers a new NGClientListener to be called on client disconnection or calls the listeners clientDisconnected method if the client has already disconnected to avoid races.- Parameters:
listener- theNGClientListenerto be notified of client events.
-
removeClientListener
public void removeClientListener(NGClientListener listener)
- Parameters:
listener- theNGClientListenerto no longer be notified of client events.
-
removeAllClientListeners
public void removeAllClientListeners()
Do not notify anymore about client disconnects
-
addHeartbeatListener
public void addHeartbeatListener(NGHeartbeatListener listener)
- Parameters:
listener- theNGHeartbeatListenerto be notified of client events.
-
removeHeartbeatListener
public void removeHeartbeatListener(NGHeartbeatListener listener)
- Parameters:
listener- theNGClientListenerto no longer be notified of client events.
-
-