/** * @param request * @param connection * @return */ public DataList handlePublisherRequest( PublishRequestTuple request, AbstractLengthPrependerClient connection) { String identifier = request.getIdentifier(); DataList dl; if (publisherBuffers.containsKey(identifier)) { /* * close previous connection with the same identifier which is guaranteed to be unique. */ AbstractLengthPrependerClient previous = publisherChannels.put(identifier, connection); if (previous != null) { eventloop.disconnect(previous); } dl = publisherBuffers.get(identifier); try { dl.rewind(request.getBaseSeconds(), request.getWindowId()); } catch (IOException ie) { throw new RuntimeException(ie); } } else { dl = Tuple.FAST_VERSION.equals(request.getVersion()) ? new FastDataList(identifier, blockSize, numberOfCacheBlocks) : new DataList(identifier, blockSize, numberOfCacheBlocks); publisherBuffers.put(identifier, dl); } dl.setSecondaryStorage(storage, storageHelperExecutor); return dl; }
@Override public void onMessage(byte[] buffer, int offset, int size) { if (ignore) { return; } Tuple request = Tuple.getTuple(buffer, offset, size); switch (request.getType()) { case PUBLISHER_REQUEST: /* * unregister the unidentified client since its job is done! */ unregistered(key); logger.info("Received publisher request: {}", request); PublishRequestTuple publisherRequest = (PublishRequestTuple) request; DataList dl = handlePublisherRequest(publisherRequest, this); dl.setAutoFlushExecutor(serverHelperExecutor); Publisher publisher; if (publisherRequest.getVersion().equals(Tuple.FAST_VERSION)) { publisher = new Publisher(dl, (long) request.getBaseSeconds() << 32 | request.getWindowId()) { @Override public int readSize() { if (writeOffset - readOffset < 2) { return -1; } short s = buffer[readOffset++]; return s | (buffer[readOffset++] << 8); } }; } else { publisher = new Publisher(dl, (long) request.getBaseSeconds() << 32 | request.getWindowId()); } key.attach(publisher); key.interestOps(SelectionKey.OP_READ); publisher.registered(key); int len = writeOffset - readOffset - size; if (len > 0) { publisher.transferBuffer(this.buffer, readOffset + size, len); } ignore = true; break; case SUBSCRIBER_REQUEST: /* * unregister the unidentified client since its job is done! */ unregistered(key); ignore = true; logger.info("Received subscriber request: {}", request); SubscribeRequestTuple subscriberRequest = (SubscribeRequestTuple) request; AbstractLengthPrependerClient subscriber; // /* for backward compatibility - set the buffer size to 16k - EXPERIMENTAL */ int bufferSize = subscriberRequest.getBufferSize(); // if (bufferSize == 0) { // bufferSize = 16 * 1024; // } if (subscriberRequest.getVersion().equals(Tuple.FAST_VERSION)) { subscriber = new Subscriber( subscriberRequest.getStreamType(), subscriberRequest.getMask(), subscriberRequest.getPartitions(), bufferSize); } else { subscriber = new Subscriber( subscriberRequest.getStreamType(), subscriberRequest.getMask(), subscriberRequest.getPartitions(), bufferSize) { @Override public int readSize() { if (writeOffset - readOffset < 2) { return -1; } short s = buffer[readOffset++]; return s | (buffer[readOffset++] << 8); } }; } key.attach(subscriber); key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ); subscriber.registered(key); final LogicalNode logicalNode = handleSubscriberRequest(subscriberRequest, subscriber); serverHelperExecutor.submit( new Runnable() { @Override public void run() { logicalNode.catchUp(); } }); break; case PURGE_REQUEST: logger.info("Received purge request: {}", request); try { handlePurgeRequest((PurgeRequestTuple) request, this); } catch (IOException io) { throw new RuntimeException(io); } break; case RESET_REQUEST: logger.info("Received reset all request: {}", request); try { handleResetRequest((ResetRequestTuple) request, this); } catch (IOException io) { throw new RuntimeException(io); } break; default: throw new RuntimeException("unexpected message: " + request.toString()); } }