@Advice.OnMethodEnter static void cleanupImageInterceptor(final PublicationImage image) { LOGGER.logImageRemoval(image.channel(), image.sessionId(), image.streamId(), image.correlationId()); } }
public void addPublicationImage(final PublicationImage image) { final int sessionId = image.sessionId(); final int streamId = image.streamId(); final StreamInterest streamInterest = streamInterestByIdMap.get(streamId); SessionInterest sessionInterest = streamInterest.sessionInterestByIdMap.get(sessionId); if (null == sessionInterest) { sessionInterest = new SessionInterest(ACTIVE); streamInterest.sessionInterestByIdMap.put(sessionId, sessionInterest); } else { sessionInterest.state = ACTIVE; } sessionInterest.image = image; image.activate(); }
public int doWork() { int workCount = commandQueue.drain(Runnable::run, Configuration.COMMAND_DRAIN_LIMIT); final int bytesReceived = dataTransportPoller.pollTransports(); totalBytesReceived.getAndAddOrdered(bytesReceived); final long nowNs = nanoClock.nanoTime(); final ArrayList<PublicationImage> publicationImages = this.publicationImages; for (int lastIndex = publicationImages.size() - 1, i = lastIndex; i >= 0; i--) { final PublicationImage image = publicationImages.get(i); if (image.hasActivityAndNotEndOfStream(nowNs)) { workCount += image.sendPendingStatusMessage(); workCount += image.processPendingLoss(); workCount += image.initiateAnyRttMeasurements(nowNs); } else { ArrayListUtil.fastUnorderedRemove(publicationImages, i, lastIndex--); image.removeFromDispatcher(); } } checkPendingSetupMessages(nowNs); return workCount + bytesReceived; }
public boolean matches(final PublicationImage image) { return image.channelEndpoint() == this.channelEndpoint && image.streamId() == this.streamId && isWildcardOrSessionIdMatch(image.sessionId()); }
public void removePublicationImage(final PublicationImage image) { final int sessionId = image.sessionId(); final int streamId = image.streamId(); final StreamInterest streamInterest = streamInterestByIdMap.get(streamId); if (null != streamInterest) { final SessionInterest sessionInterest = streamInterest.sessionInterestByIdMap.get(sessionId); if (null != sessionInterest && null != sessionInterest.image) { if (sessionInterest.image.correlationId() == image.correlationId()) { sessionInterest.state = ON_COOL_DOWN; sessionInterest.image = null; } } } image.ifActiveGoInactive(); }
private void linkMatchingImages(final SubscriptionLink subscription) { final long registrationId = subscription.registrationId(); final int streamId = subscription.streamId(); final String channel = subscription.channel(); for (int i = 0, size = publicationImages.size(); i < size; i++) { final PublicationImage image = publicationImages.get(i); if (subscription.matches(image) && image.isAcceptingSubscriptions()) { final long rebuildPosition = image.rebuildPosition(); final int sessionId = image.sessionId(); final Position position = SubscriberPos.allocate( tempBuffer, countersManager, registrationId, sessionId, streamId, channel, rebuildPosition); position.setOrdered(rebuildPosition); image.addSubscriber(position); subscription.link(image, position); clientProxy.onAvailableImage( image.correlationId(), streamId, sessionId, registrationId, position.id(), image.rawLog().fileName(), generateSourceIdentity(image.sourceAddress())); } } }
@Test public void shouldNotRemoveImageFromDispatcherOnRemoveSubscription() { receiverProxy.registerReceiveChannelEndpoint(receiveChannelEndpoint); receiverProxy.addSubscription(receiveChannelEndpoint, STREAM_ID); receiver.doWork(); fillSetupFrame(setupHeader); receiveChannelEndpoint.onSetupMessage(setupHeader, setupBuffer, SetupFlyweight.HEADER_LENGTH, senderAddress, 0); final PublicationImage mockImage = mock(PublicationImage.class); when(mockImage.sessionId()).thenReturn(SESSION_ID); when(mockImage.streamId()).thenReturn(STREAM_ID); when(mockImage.hasActivityAndNotEndOfStream(anyLong())).thenReturn(true); receiver.onNewPublicationImage(receiveChannelEndpoint, mockImage); receiver.onRemoveSubscription(receiveChannelEndpoint, STREAM_ID); receiver.doWork(); verify(mockImage).ifActiveGoInactive(); verify(mockImage, never()).removeFromDispatcher(); }
@Test public void shouldNotRemoveNewPublicationImageFromOldRemovePublicationImageAfterRemoveSubscription() { final PublicationImage mockImage1 = mock(PublicationImage.class); final PublicationImage mockImage2 = mock(PublicationImage.class); when(mockImage1.sessionId()).thenReturn(SESSION_ID); when(mockImage1.streamId()).thenReturn(STREAM_ID); when(mockImage1.correlationId()).thenReturn(CORRELATION_ID_1); when(mockImage2.sessionId()).thenReturn(SESSION_ID); when(mockImage2.streamId()).thenReturn(STREAM_ID); when(mockImage2.correlationId()).thenReturn(CORRELATION_ID_2); dispatcher.addSubscription(STREAM_ID); dispatcher.addPublicationImage(mockImage1); dispatcher.removeSubscription(STREAM_ID); dispatcher.addSubscription(STREAM_ID); dispatcher.addPublicationImage(mockImage2); dispatcher.removePublicationImage(mockImage1); dispatcher.onDataPacket(mockChannelEndpoint, mockHeader, mockBuffer, LENGTH, SRC_ADDRESS, 0); verify(mockImage1, never()).insertPacket(anyInt(), anyInt(), any(), anyInt(), anyInt(), any()); verify(mockImage2).insertPacket(ACTIVE_TERM_ID, TERM_OFFSET, mockBuffer, LENGTH, 0, SRC_ADDRESS); }
@Test public void shouldSignalInactiveImageWhenImageTimesOut() { final InetSocketAddress sourceAddress = new InetSocketAddress("localhost", 4400); final long subId = driverProxy.addSubscription(CHANNEL_4000, STREAM_ID_1); driverConductor.doWork(); final ReceiveChannelEndpoint receiveChannelEndpoint = driverConductor.receiverChannelEndpoint(UdpChannel.parse(CHANNEL_4000)); assertNotNull(receiveChannelEndpoint); receiveChannelEndpoint.openChannel(driverConductorProxy); driverConductor.onCreatePublicationImage( SESSION_ID, STREAM_ID_1, 1, 1, 0, TERM_BUFFER_LENGTH, MTU_LENGTH, 0, mock(InetSocketAddress.class), sourceAddress, receiveChannelEndpoint); final ArgumentCaptor<PublicationImage> captor = ArgumentCaptor.forClass(PublicationImage.class); verify(receiverProxy).newPublicationImage(eq(receiveChannelEndpoint), captor.capture()); final PublicationImage publicationImage = captor.getValue(); publicationImage.activate(); publicationImage.ifActiveGoInactive(); doWorkUntil(() -> nanoClock.nanoTime() >= IMAGE_LIVENESS_TIMEOUT_NS + 1000); verify(mockClientProxy).onUnavailableImage( eq(publicationImage.correlationId()), eq(subId), eq(STREAM_ID_1), anyString()); }
receiveChannelEndpoint.onSetupMessage(setupHeader, setupBuffer, SetupFlyweight.HEADER_LENGTH, senderAddress, 0); final PublicationImage image = new PublicationImage( CORRELATION_ID, Configuration.IMAGE_LIVENESS_TIMEOUT_NS, image.trackRebuild(currentTime + (2 * STATUS_MESSAGE_TIMEOUT), STATUS_MESSAGE_TIMEOUT); image.sendPendingStatusMessage();
@Before public void setUp() { when(mockHeader.sessionId()).thenReturn(SESSION_ID); when(mockHeader.streamId()).thenReturn(STREAM_ID); when(mockHeader.termId()).thenReturn(ACTIVE_TERM_ID); when(mockHeader.termOffset()).thenReturn(TERM_OFFSET); when(mockImage.sessionId()).thenReturn(SESSION_ID); when(mockImage.streamId()).thenReturn(STREAM_ID); when(mockSetupHeader.sessionId()).thenReturn(SESSION_ID); when(mockSetupHeader.streamId()).thenReturn(STREAM_ID); when(mockSetupHeader.activeTermId()).thenReturn(ACTIVE_TERM_ID); when(mockSetupHeader.initialTermId()).thenReturn(INITIAL_TERM_ID); when(mockSetupHeader.termOffset()).thenReturn(TERM_OFFSET); when(mockSetupHeader.mtuLength()).thenReturn(MTU_LENGTH); when(mockSetupHeader.termLength()).thenReturn(TERM_LENGTH); }
@Test public void shouldSetImageInactiveOnRemoveImage() { dispatcher.addSubscription(STREAM_ID); dispatcher.addPublicationImage(mockImage); dispatcher.removePublicationImage(mockImage); verify(mockImage).ifActiveGoInactive(); }
@Test public void shouldDispatchDataToCorrectImage() { dispatcher.addSubscription(STREAM_ID); dispatcher.addPublicationImage(mockImage); dispatcher.onDataPacket(mockChannelEndpoint, mockHeader, mockBuffer, LENGTH, SRC_ADDRESS, 0); verify(mockImage).activate(); verify(mockImage).insertPacket(ACTIVE_TERM_ID, TERM_OFFSET, mockBuffer, LENGTH, 0, SRC_ADDRESS); }
@Test public void shouldElicitSetupMessageWhenDataArrivesForSubscriptionWithoutImage() { dispatcher.addSubscription(STREAM_ID); dispatcher.onDataPacket(mockChannelEndpoint, mockHeader, mockBuffer, LENGTH, SRC_ADDRESS, 0); verify(mockImage, never()).insertPacket(anyInt(), anyInt(), any(), anyInt(), anyInt(), any()); verify(mockChannelEndpoint).sendSetupElicitingStatusMessage(0, SRC_ADDRESS, SESSION_ID, STREAM_ID); verify(mockReceiver).addPendingSetupMessage(SESSION_ID, STREAM_ID, 0, mockChannelEndpoint, false, SRC_ADDRESS); }
final PublicationImage image = new PublicationImage( CORRELATION_ID, Configuration.IMAGE_LIVENESS_TIMEOUT_NS,
/** * Called from the {@link LossDetector} when gap is detected by the {@link DriverConductor} thread. * * @see LossHandler */ public void onGapDetected(final int termId, final int termOffset, final int length) { final long changeNumber = beginLossChange + 1; beginLossChange = changeNumber; lossTermId = termId; lossTermOffset = termOffset; lossLength = length; endLossChange = changeNumber; if (null != reportEntry) { reportEntry.recordObservation(length, cachedEpochClock.time()); } else if (null != lossReport) { reportEntry = lossReport.createEntry( length, cachedEpochClock.time(), sessionId, streamId, channel(), sourceAddress.toString()); if (null == reportEntry) { lossReport = null; } } }
private void linkMatchingImages(final SubscriptionLink subscription) { final long registrationId = subscription.registrationId(); final int streamId = subscription.streamId(); final String channel = subscription.channel(); for (int i = 0, size = publicationImages.size(); i < size; i++) { final PublicationImage image = publicationImages.get(i); if (subscription.matches(image) && image.isAcceptingSubscriptions()) { final long rebuildPosition = image.rebuildPosition(); final int sessionId = image.sessionId(); final Position position = SubscriberPos.allocate( tempBuffer, countersManager, registrationId, sessionId, streamId, channel, rebuildPosition); position.setOrdered(rebuildPosition); image.addSubscriber(position); subscription.link(image, position); clientProxy.onAvailableImage( image.correlationId(), streamId, sessionId, registrationId, position.id(), image.rawLog().fileName(), generateSourceIdentity(image.sourceAddress())); } } }
public void removePublicationImage(final PublicationImage image) { final int sessionId = image.sessionId(); final int streamId = image.streamId(); final StreamInterest streamInterest = streamInterestByIdMap.get(streamId); if (null != streamInterest) { final SessionInterest sessionInterest = streamInterest.sessionInterestByIdMap.get(sessionId); if (null != sessionInterest && null != sessionInterest.image) { if (sessionInterest.image.correlationId() == image.correlationId()) { sessionInterest.state = ON_COOL_DOWN; sessionInterest.image = null; } } } image.ifActiveGoInactive(); }
@Test public void shouldRemoveImageFromDispatcherWithNoActivity() { receiverProxy.registerReceiveChannelEndpoint(receiveChannelEndpoint); receiverProxy.addSubscription(receiveChannelEndpoint, STREAM_ID); receiver.doWork(); fillSetupFrame(setupHeader); receiveChannelEndpoint.onSetupMessage(setupHeader, setupBuffer, SetupFlyweight.HEADER_LENGTH, senderAddress, 0); final PublicationImage mockImage = mock(PublicationImage.class); when(mockImage.sessionId()).thenReturn(SESSION_ID); when(mockImage.streamId()).thenReturn(STREAM_ID); when(mockImage.hasActivityAndNotEndOfStream(anyLong())).thenReturn(false); receiver.onNewPublicationImage(receiveChannelEndpoint, mockImage); receiver.doWork(); verify(mockImage).removeFromDispatcher(); }
public boolean matches(final PublicationImage image) { return image.channelEndpoint() == this.channelEndpoint && image.streamId() == this.streamId && isWildcardOrSessionIdMatch(image.sessionId()); }