public void Conclude() { if (null == _aeron) { _aeron = Adaptive.Aeron.Aeron.Connect( new Aeron.Aeron.Context() .AeronDirectoryName(_aeronDirectoryName) .ErrorHandler(_errorHandler)); _ownsAeronClient = true; } if (null == _idleStrategy) { _idleStrategy = new BackoffIdleStrategy(1, 10, 1, 1); } if (null == _credentialsSupplier) { _credentialsSupplier = new NullCredentialsSupplier(); } if (null == _sessionMessageListener) { _sessionMessageListener = new MissingSessionMessageListner(); } }
internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) { this.ctx = ctx; headerVector = new DirectBufferVector(headerBuffer, 0, headerBuffer.Capacity); abortHandler = Abort; archiveCtx = ctx.ArchiveContext(); aeron = ctx.Aeron(); aeronAgentInvoker = ctx.Aeron().ConductorAgentInvoker; service = ctx.ClusteredService(); idleStrategy = ctx.IdleStrategy(); serviceId = ctx.ServiceId(); epochClock = ctx.EpochClock(); markFile = ctx.MarkFile(); var channel = ctx.ServiceControlChannel(); _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId())); _serviceAdapter = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this); _sessionMessageHeaderEncoder.WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder()); aeron.AddCloseHandler(abortHandler); }
internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) { this.ctx = ctx; archiveCtx = ctx.ArchiveContext(); aeron = ctx.Aeron(); service = ctx.ClusteredService(); idleStrategy = ctx.IdleStrategy(); serviceId = ctx.ServiceId(); epochClock = ctx.EpochClock(); markFile = ctx.MarkFile(); var channel = ctx.ServiceControlChannel(); _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId())); _serviceAdapter = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this); UnsafeBuffer headerBuffer = new UnsafeBuffer(new byte[SESSION_HEADER_LENGTH]); _egressMessageHeaderEncoder.WrapAndApplyHeader(headerBuffer, 0, new MessageHeaderEncoder()); _vectors[0] = new DirectBufferVector(headerBuffer, 0, SESSION_HEADER_LENGTH); _vectors[1] = _messageVector; }
/// <summary> /// Create a proxy with a <seealso cref="Publication"/> for sending control message requests. /// </summary> /// <param name="publication"> publication for sending control messages to an archive. </param> /// <param name="retryIdleStrategy"> for what should happen between retry attempts at offering messages. </param> /// <param name="nanoClock"> to be used for calculating checking deadlines. </param> /// <param name="connectTimeoutNs"> for for connection requests. </param> /// <param name="retryAttempts"> for offering control messages before giving up. </param> public ArchiveProxy(Publication publication, IIdleStrategy retryIdleStrategy, INanoClock nanoClock, long connectTimeoutNs, int retryAttempts) { this.publication = publication; this.retryIdleStrategy = retryIdleStrategy; this.nanoClock = nanoClock; this.connectTimeoutNs = connectTimeoutNs; this.retryAttempts = retryAttempts; }
/// <summary> /// Return a reusable, parameterized event loop that calls and idler when no messages are received /// </summary> /// <param name="fragmentHandler"> to be called back for each message. </param> /// <param name="limit"> passed to <seealso cref="Subscription#poll(FragmentHandler, int)"/> </param> /// <param name="running"> indication for loop </param> /// <param name="idleStrategy"> to use for loop </param> /// <returns> loop function </returns> public static Action<Subscription> SubscriberLoop(FragmentHandler fragmentHandler, int limit, AtomicBoolean running, IIdleStrategy idleStrategy) { return subscription => { while (running.Get()) { idleStrategy.Idle(subscription.Poll(fragmentHandler, limit)); } }; }
/// <summary> /// Create an agent passing in <seealso cref="_idleStrategy"/> /// </summary> /// <param name="idleStrategy"> to use for Agent run loop </param> /// <param name="errorHandler"> to be called if an <seealso cref="Exception"/> is encountered </param> /// <param name="errorCounter"> for reporting how many exceptions have been seen. </param> /// <param name="agent"> to be run in this thread. </param> public AgentRunner(IIdleStrategy idleStrategy, ErrorHandler errorHandler, AtomicCounter errorCounter, IAgent agent) { if (idleStrategy == null) throw new ArgumentNullException(nameof(idleStrategy)); if (errorHandler == null) throw new ArgumentNullException(nameof(errorHandler)); if (agent == null) throw new ArgumentNullException(nameof(agent)); _idleStrategy = idleStrategy; _errorHandler = errorHandler; _errorCounter = errorCounter; _agent = agent; }
/// <summary> /// Creates a new Aeron target with the specified parameters. /// </summary> /// <param name="aeron">the Aeron connection to use</param> /// <param name="stream">the Aeron stream ID to use</param> /// <param name="channel">the Aeron channel to use</param> /// <param name="idleStrategy">the Aeron idle strategy to use</param> /// <param name="fragmentLimit">the number of message fragments to process per poll operation</param> public Target( Aeron aeron, int stream, string channel, IIdleStrategy idleStrategy, int fragmentLimit ) { _stream = stream; _channel = channel; _subscription = aeron.AddSubscription(_channel, _stream); _idleStrategy = idleStrategy; _fragmentLimit = fragmentLimit; }
private AeronCluster(Context ctx) { _ctx = ctx; Subscription subscription = null; try { ctx.Conclude(); _aeron = ctx.Aeron(); _idleStrategy = ctx.IdleStrategy(); _nanoClock = _aeron.Ctx().NanoClock(); _isUnicast = ctx.ClusterMemberEndpoints() != null; UpdateMemberEndpoints(ctx.ClusterMemberEndpoints()); subscription = _aeron.AddSubscription(ctx.EgressChannel(), ctx.EgressStreamId()); _subscription = subscription; _publication = ConnectToCluster(); _clusterSessionId = OpenSession(); UnsafeBuffer headerBuffer = new UnsafeBuffer(new byte[SessionDecorator.SESSION_HEADER_LENGTH]); _sessionHeaderEncoder .WrapAndApplyHeader(headerBuffer, 0, _messageHeaderEncoder) .ClusterSessionId(_clusterSessionId) .Timestamp(Aeron.Aeron.NULL_VALUE); _vectors[0] = new DirectBufferVector(headerBuffer, 0, SessionDecorator.SESSION_HEADER_LENGTH); _vectors[1] = _messageBuffer; _poller = new Poller(ctx.SessionMessageListener(), _clusterSessionId, this); _fragmentAssembler = new FragmentAssembler(_poller); } catch (Exception) { if (!ctx.OwnsAeronClient()) { CloseHelper.QuietDispose(_publication); CloseHelper.QuietDispose(subscription); } CloseHelper.QuietDispose(ctx); throw; } }
internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) { this.ctx = ctx; archiveCtx = ctx.ArchiveContext(); aeron = ctx.Aeron(); service = ctx.ClusteredService(); idleStrategy = ctx.IdleStrategy(); serviceId = ctx.ServiceId(); epochClock = ctx.EpochClock(); markFile = ctx.MarkFile(); var channel = ctx.ServiceControlChannel(); _consensusModuleProxy = new ConsensusModuleProxy(aeron.AddPublication(channel, ctx.ConsensusModuleStreamId())); _serviceAdapter = new ServiceAdapter(aeron.AddSubscription(channel, ctx.ServiceStreamId()), this); }
internal ClientConductor(Aeron.Context ctx, Aeron aeron) { _ctx = ctx; _aeron = aeron; _clientLock = ctx.ClientLock(); _epochClock = ctx.EpochClock(); _nanoClock = ctx.NanoClock(); _awaitingIdleStrategy = ctx.AwaitingIdleStrategy(); _driverProxy = ctx.DriverProxy(); _logBuffersFactory = ctx.LogBuffersFactory(); _keepAliveIntervalNs = ctx.KeepAliveIntervalNs(); _driverTimeoutMs = ctx.DriverTimeoutMs(); _driverTimeoutNs = _driverTimeoutMs * 1000000; _interServiceTimeoutNs = ctx.InterServiceTimeoutNs(); _defaultAvailableImageHandler = ctx.AvailableImageHandler(); _defaultUnavailableImageHandler = ctx.UnavailableImageHandler(); _driverEventsAdapter = new DriverEventsAdapter(ctx.ToClientBuffer(), ctx.ClientId(), this, _asyncCommandIdSet); _driverAgentInvoker = ctx.DriverAgentInvoker(); _counterValuesBuffer = ctx.CountersValuesBuffer(); _countersReader = new CountersReader(ctx.CountersMetaDataBuffer(), ctx.CountersValuesBuffer(), Encoding.ASCII); if (null != ctx.AvailableCounterHandler()) { _availableCounterHandlers.Add(ctx.AvailableCounterHandler()); } if (null != ctx.UnavailableCounterHandler()) { _unavailableCounterHandlers.Add(ctx.UnavailableCounterHandler()); } if (null != ctx.CloseHandler()) { _closeHandlers.Add(ctx.CloseHandler()); } long nowNs = _nanoClock.NanoTime(); _timeOfLastKeepAliveNs = nowNs; _timeOfLastServiceNs = nowNs; }
/// <summary> /// Create an agent passing in <seealso cref="_idleStrategy"/> /// </summary> /// <param name="idleStrategy"> to use for Agent run loop </param> /// <param name="errorHandler"> to be called if an <seealso cref="Exception"/> is encountered </param> /// <param name="errorCounter"> for reporting how many exceptions have been seen. </param> /// <param name="agent"> to be run in this thread. </param> public AgentRunner(IIdleStrategy idleStrategy, ErrorHandler errorHandler, AtomicCounter errorCounter, IAgent agent) { if (idleStrategy == null) { throw new ArgumentNullException(nameof(idleStrategy)); } if (errorHandler == null) { throw new ArgumentNullException(nameof(errorHandler)); } if (agent == null) { throw new ArgumentNullException(nameof(agent)); } _idleStrategy = idleStrategy; _errorHandler = errorHandler; _errorCounter = errorCounter; _agent = agent; }
internal ClusteredServiceAgent(ClusteredServiceContainer.Context ctx) { this.ctx = ctx; archiveCtx = ctx.ArchiveContext(); aeron = ctx.Aeron(); shouldCloseResources = ctx.OwnsAeronClient(); service = ctx.ClusteredService(); recordingLog = ctx.RecordingLog(); idleStrategy = ctx.IdleStrategy(); serviceId = ctx.ServiceId(); epochClock = ctx.EpochClock(); markFile = ctx.MarkFile(); var channel = ctx.ServiceControlChannel(); var streamId = ctx.ServiceControlStreamId(); serviceControlPublisher = new ServiceControlPublisher(aeron.AddPublication(channel, streamId)); serviceControlAdapter = new ServiceControlAdapter(aeron.AddSubscription(channel, streamId), this); }
private bool DoDutyCycle(IIdleStrategy idleStrategy, IAgent agent) { try { idleStrategy.Idle(agent.DoWork()); } catch (ThreadInterruptedException) { return(true); } catch (AgentTerminationException ex) { HandleError(ex); return(true); } catch (Exception ex) { HandleError(ex); } return(false); }
private static void Publish <T>(T message, Publication publication, IIdleStrategy offerIdleStrategy, IMutableDirectBuffer buffer) { var serTm = Util.Serialize(message); var length = serTm.Length; buffer.PutBytes(0, serTm); offerIdleStrategy.Reset(); while (!Offer(publication, buffer, length)) { // The offer failed, which is usually due to the publication // being temporarily blocked. Retry the offer after a short // spin/yield/sleep, depending on the chosen IdleStrategy. //backPressureCount++; offerIdleStrategy.Idle(); } //reporter.OnMessage(1, length); }
public void Conclude() { if (null == _aeron) { _aeron = Adaptive.Aeron.Aeron.Connect(new Aeron.Aeron.Context().AeronDirectoryName(_aeronDirectoryName)); _ownsAeronClient = true; } if (null == _idleStrategy) { _idleStrategy = new BackoffIdleStrategy(1, 10, 1, 1); } if (null == _lock) { _lock = new ReentrantLock(); } if (null == _credentialsSupplier) { _credentialsSupplier = new NullCredentialsSupplier(); } }
private AeronCluster(Context ctx) { _ctx = ctx; Subscription subscription = null; Publication publication = null; try { ctx.Conclude(); _aeron = ctx.Aeron(); _lock = ctx.Lock(); _idleStrategy = ctx.IdleStrategy(); _nanoClock = _aeron.Ctx().NanoClock(); _isUnicast = ctx.ClusterMemberEndpoints() != null; subscription = _aeron.AddSubscription(ctx.EgressChannel(), ctx.EgressStreamId()); _subscription = subscription; publication = ConnectToCluster(); _publication = publication; _clusterSessionId = OpenSession(); } catch (Exception) { if (!ctx.OwnsAeronClient()) { CloseHelper.QuietDispose(publication); CloseHelper.QuietDispose(subscription); } CloseHelper.QuietDispose(ctx); throw; } }
public AeronServer(int serverPort, ClientServerConfig config) { _config = config; _driverContext = config.ToDriverContext(); _clientContext = config.ToClientContext(); _driverContext .LoggerInfo(_driverLog.Info) .LoggerWarning(_driverLog.Warn) .LoggerWarning(_driverLog.Error); _driver = AeronDriver.Start(_driverContext); _clientContext .ErrorHandler(OnError) .AvailableImageHandler(ConnectionOnImageAvailable) .UnavailableImageHandler(ConnectionOnImageUnavailable); _client = Adaptive.Aeron.Aeron.Connect(_clientContext); _publicationIdleStrategy = _config.ClientIdleStrategy.GetClientIdleStrategy(); _subscription = _client.AddSubscription($"aeron:udp?endpoint=0.0.0.0:{serverPort}", ServerStreamId); }
/// <summary> /// This is called automatically by <seealso cref="Connect()"/> and its overloads. /// There is no need to call it from a client application. It is responsible for providing default /// values for options that are not individually changed through field setters. /// </summary> /// <returns> this Aeron.Context for method chaining. </returns> public Context Conclude() { try { _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE)); if (_epochClock == null) { _epochClock = new SystemEpochClock(); } if (_nanoClock == null) { _nanoClock = new SystemNanoClock(); } if (_idleStrategy == null) { _idleStrategy = new SleepingIdleStrategy(IdleSleepMs); } if (CncFile() != null) { _cncByteBuffer = IoUtil.MapExistingFile(CncFile().FullName); _cncMetaDataBuffer = CncFileDescriptor.CreateMetaDataBuffer(_cncByteBuffer); var cncVersion = _cncMetaDataBuffer.GetInt(CncFileDescriptor.CncVersionOffset(0)); if (CncFileDescriptor.CNC_VERSION != cncVersion) { throw new InvalidOperationException( "aeron cnc file version not understood: version=" + cncVersion); } } if (_toClientBuffer == null) { var receiver = new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer, _cncMetaDataBuffer)); _toClientBuffer = new CopyBroadcastReceiver(receiver); } if (_toDriverBuffer == null) { _toDriverBuffer = new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersMetaDataBuffer() == null) { CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersValuesBuffer() == null) { CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer); if (_logBuffersFactory == null) { _logBuffersFactory = new MappedLogBuffersFactory(); } if (_errorHandler == null) { _errorHandler = DEFAULT_ERROR_HANDLER; } if (_availableImageHandler == null) { _availableImageHandler = image => { }; } if (_unavailableImageHandler == null) { _unavailableImageHandler = image => { }; } } catch ( Exception ex) { Console.WriteLine("***"); Console.WriteLine("***"); Console.WriteLine("Failed to connect to the Media Driver - is it currently running?"); Console.WriteLine("***"); Console.WriteLine("***"); throw new InvalidOperationException("Could not initialise communication buffers", ex); } return this; }
/// <summary> /// Provides an IdleStrategy for the thread responsible for communicating with the Aeron Media Driver. /// </summary> /// <param name="idleStrategy"> Thread idle strategy for communication with the Media Driver. </param> /// <returns> this Aeron.Context for method chaining. </returns> public Context IdleStrategy(IIdleStrategy idleStrategy) { _idleStrategy = idleStrategy; return this; }
/// <summary> /// This is called automatically by <seealso cref="Connect()"/> and its overloads. /// There is no need to call it from a client application. It is responsible for providing default /// values for options that are not individually changed through field setters. /// </summary> /// <returns> this Aeron.Context for method chaining. </returns> public Context Conclude() { try { _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE)); if (_epochClock == null) { _epochClock = new SystemEpochClock(); } if (_nanoClock == null) { _nanoClock = new SystemNanoClock(); } if (_idleStrategy == null) { _idleStrategy = new SleepingIdleStrategy(IdleSleepMs); } if (CncFile() != null) { _cncByteBuffer = IoUtil.MapExistingFile(CncFile().FullName); _cncMetaDataBuffer = CncFileDescriptor.CreateMetaDataBuffer(_cncByteBuffer); var cncVersion = _cncMetaDataBuffer.GetInt(CncFileDescriptor.CncVersionOffset(0)); if (CncFileDescriptor.CNC_VERSION != cncVersion) { throw new InvalidOperationException( "aeron cnc file version not understood: version=" + cncVersion); } } if (_toClientBuffer == null) { var receiver = new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer, _cncMetaDataBuffer)); _toClientBuffer = new CopyBroadcastReceiver(receiver); } if (_toDriverBuffer == null) { _toDriverBuffer = new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersMetaDataBuffer() == null) { CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersValuesBuffer() == null) { CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer); if (_logBuffersFactory == null) { _logBuffersFactory = new MappedLogBuffersFactory(); } if (_errorHandler == null) { _errorHandler = DEFAULT_ERROR_HANDLER; } if (_availableImageHandler == null) { _availableImageHandler = image => { }; } if (_unavailableImageHandler == null) { _unavailableImageHandler = image => { }; } } catch ( Exception ex) { Console.WriteLine("***"); Console.WriteLine("***"); Console.WriteLine("Failed to connect to the Media Driver - is it currently running?"); Console.WriteLine("***"); Console.WriteLine("***"); throw new InvalidOperationException("Could not initialise communication buffers", ex); } return(this); }
/// <summary> /// Provides an IdleStrategy for the thread responsible for communicating with the Aeron Media Driver. /// </summary> /// <param name="idleStrategy"> Thread idle strategy for communication with the Media Driver. </param> /// <returns> this Aeron.Context for method chaining. </returns> public Context IdleStrategy(IIdleStrategy idleStrategy) { _idleStrategy = idleStrategy; return(this); }
/// <summary> /// This is called automatically by <seealso cref="Connect()"/> and its overloads. /// There is no need to call it from a client application. It is responsible for providing default /// values for options that are not individually changed through field setters. /// </summary> /// <returns> this Aeron.Context for method chaining. </returns> public Context Conclude() { _cncFile = new FileInfo(Path.Combine(_aeronDirectoryName, CncFileDescriptor.CNC_FILE)); if (_epochClock == null) { _epochClock = new SystemEpochClock(); } if (_nanoClock == null) { _nanoClock = new SystemNanoClock(); } if (_idleStrategy == null) { _idleStrategy = new SleepingIdleStrategy(IdleSleepMs); } if (CncFile() != null) { ConnectToDriver(); } if (_toClientBuffer == null) { var receiver = new BroadcastReceiver(CncFileDescriptor.CreateToClientsBuffer(_cncByteBuffer, _cncMetaDataBuffer)); _toClientBuffer = new CopyBroadcastReceiver(receiver); } if (_toDriverBuffer == null) { _toDriverBuffer = new ManyToOneRingBuffer(CncFileDescriptor.CreateToDriverBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersMetaDataBuffer() == null) { CountersMetaDataBuffer(CncFileDescriptor.CreateCountersMetaDataBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } if (CountersValuesBuffer() == null) { CountersValuesBuffer(CncFileDescriptor.CreateCountersValuesBuffer(_cncByteBuffer, _cncMetaDataBuffer)); } _interServiceTimeout = CncFileDescriptor.ClientLivenessTimeout(_cncMetaDataBuffer); if (_logBuffersFactory == null) { _logBuffersFactory = new MappedLogBuffersFactory(); } if (_errorHandler == null) { _errorHandler = DEFAULT_ERROR_HANDLER; } if (_availableImageHandler == null) { _availableImageHandler = image => { }; } if (_unavailableImageHandler == null) { _unavailableImageHandler = image => { }; } return(this); }
public SnapshotTaker(Publication publication, IIdleStrategy idleStrategy, AgentInvoker aeronClientInvoker) { this.publication = publication; this.idleStrategy = idleStrategy; this.aeronClientInvoker = aeronClientInvoker; }
internal ServiceSnapshotTaker(Publication publication, IIdleStrategy idleStrategy, AgentInvoker aeronClientInvoker) : base(publication, idleStrategy, aeronClientInvoker) { }
/// <summary> /// Return a reusable, parameterized event loop that calls and idler when no messages are received /// </summary> /// <param name="fragmentHandler"> to be called back for each message. </param> /// <param name="limit"> passed to <seealso cref="Subscription#poll(FragmentHandler, int)"/> </param> /// <param name="running"> indication for loop </param> /// <param name="idleStrategy"> to use for loop </param> /// <returns> loop function </returns> public static Action <Subscription> SubscriberLoop(IFragmentHandler fragmentHandler, int limit, AtomicBoolean running, IIdleStrategy idleStrategy) { return(subscription => { while (running) { idleStrategy.Idle(subscription.Poll(fragmentHandler, limit)); } }); }