public StateActionWithContextScheduledAsyncTask(AbstractScheduledEventExecutor executor, Action<object, object> action, object context, object state, PreciseTimeSpan deadline, CancellationToken cancellationToken) : base(executor, deadline, new TaskCompletionSource(state), cancellationToken) { this.action = action; this.context = context; }
public void Register(PreciseTimeSpan startTimestamp) { PreciseTimeSpan elapsed = PreciseTimeSpan.FromStart - startTimestamp; long elapsedMs = (long)elapsed.ToTimeSpan().TotalMilliseconds; this.countCounter.IncrementBy(elapsedMs); this.baseCounter.Increment(); }
public CompletionPendingMessageState(int packetId, string lockToken, IQos2MessageDeliveryState deliveryState, PreciseTimeSpan startTimestamp) { this.PacketId = packetId; this.LockToken = lockToken; this.DeliveryState = deliveryState; this.StartTimestamp = startTimestamp; this.SentTime = DateTime.UtcNow; }
public CompletionPendingMessageState(int packetId, IQos2MessageDeliveryState deliveryState, PreciseTimeSpan startTimestamp, MessageFeedbackChannel feedbackChannel) { this.PacketId = packetId; this.DeliveryState = deliveryState; this.StartTimestamp = startTimestamp; this.FeedbackChannel = feedbackChannel; this.SentTime = DateTime.UtcNow; }
public void TestScheduling() { var ch = new EmbeddedChannel(new ChannelHandlerAdapter()); var latch = new CountdownEvent(2); Task future = ch.EventLoop.ScheduleAsync(() => latch.Signal(), TimeSpan.FromSeconds(1)); future.ContinueWith(t => latch.Signal()); PreciseTimeSpan next = ch.RunScheduledPendingTasks(); Assert.True(next > PreciseTimeSpan.Zero); // Sleep for the nanoseconds but also give extra 50ms as the clock my not be very precise and so fail the test // otherwise. Thread.Sleep(next.ToTimeSpan() + TimeSpan.FromMilliseconds(50)); Assert.Equal(PreciseTimeSpan.MinusOne, ch.RunScheduledPendingTasks()); latch.Wait(); }
async Task PublishToServerAsync(IChannelHandlerContext context, PublishPacket packet) { if (!this.ConnectedToHub) { return; } PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart; this.ResumeReadingIfNecessary(context); using (Stream bodyStream = packet.Payload.IsReadable() ? new ReadOnlyByteBufferStream(packet.Payload, true) : null) { var message = new Message(bodyStream); this.ApplyRoutingConfiguration(message, packet); Util.CompleteMessageFromPacket(message, packet, this.settings); await this.iotHubClient.SendAsync(message); PerformanceCounters.MessagesSentPerSecond.Increment(); } if (!this.IsInState(StateFlags.Closed)) { switch (packet.QualityOfService) { case QualityOfService.AtMostOnce: // no response necessary PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp); break; case QualityOfService.AtLeastOnce: Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet)) .OnFault(ShutdownOnWriteFaultAction, context); PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp); // todo: assumes PUBACK is written out sync break; case QualityOfService.ExactlyOnce: ShutdownOnError(context, "QoS 2 is not supported."); break; default: throw new InvalidOperationException("Unexpected QoS level: " + packet.QualityOfService); } } }
async void SendD2CMessage(DeviceDataPacket dataPacket) { Contract.Requires(this.identity != null); if (identity?.Id != dataPacket.DeviceId) { if (this.stateFlags == StateFlags.ProcessingConnect || this.stateFlags == StateFlags.Connected) { this.stateFlags = StateFlags.InvalidConfiguration; this.Shutdown(this.capturedContext, new SocketIoTGatewayException(ErrorCode.UnResolvedSendingClient, "Invalid device identity")); return; } } if (this.ConnectedToService) { PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart; IMessage message = null; try { ITcpIoTHubMessagingServiceClient sendingClient = null; if (this.messagingBridge.TryResolveClient("Events", out sendingClient)) { message = sendingClient.CreateMessage(dataPacket.EventTopicAddress, dataPacket.Payload); message.Properties[this.settings.ServicePropertyPrefix + "MessageType"] = dataPacket.PacketType.ToString(); await sendingClient.SendAsync(message); message = null; } else { throw new SocketIoTGatewayException(ErrorCode.UnResolvedSendingClient, $"Could not resolve a sending client based on topic name `Events`."); } } finally { message?.Dispose(); } } else { dataPacket.Release(); } }
void FetchFromScheduledTaskQueue() { if (this.HasScheduledTasks()) { PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; while (true) { ScheduledTaskQueueNode scheduledTask = this.PollScheduledTask(nanoTime); if (scheduledTask == null) { break; } this.taskQueue.Enqueue(scheduledTask); this.semaphore.Release(); } } }
bool FetchFromScheduledTaskQueue() { PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; IScheduledRunnable scheduledTask = this.PollScheduledTask(nanoTime); while (scheduledTask != null) { if (!this.taskQueue.TryEnqueue(scheduledTask)) { // No space left in the task queue add it back to the scheduledTaskQueue so we pick it up again. this.ScheduledTaskQueue.Enqueue(scheduledTask); return(false); } scheduledTask = this.PollScheduledTask(nanoTime); } return(true); }
void FetchFromScheduledTaskQueue() { if (this.HasScheduledTasks()) { PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; while (true) { IScheduledRunnable scheduledTask = this.PollScheduledTask(nanoTime); if (scheduledTask == null) { break; } this.taskQueue.Enqueue(scheduledTask); } } }
public static async Task EventuallyAsync(Func <Task <bool> > testFunc, TimeSpan interval, TimeSpan timeout) { PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout); while (true) { if (await testFunc()) { return; } if (PreciseTimeSpan.FromStart - deadline > PreciseTimeSpan.Zero) { Assert.True(false, "Did not reach expected state in time."); } await Task.Delay(interval); } }
ScheduledTaskQueueNode PollScheduledTask(PreciseTimeSpan nanoTime) { Debug.Assert(this.InEventLoop); ScheduledTaskQueueNode scheduledTask = this.scheduledTaskQueue.Peek(); if (scheduledTask == null) { return(null); } if (scheduledTask.Deadline <= nanoTime) { this.scheduledTaskQueue.Dequeue(); return(scheduledTask); } return(null); }
protected IScheduledRunnable PollScheduledTask(PreciseTimeSpan nanoTime) { Contract.Assert(this.InEventLoop); IScheduledRunnable scheduledTask = this.ScheduledTaskQueue.Peek(); if (scheduledTask == null) { return(null); } if (scheduledTask.Deadline <= nanoTime) { this.ScheduledTaskQueue.Dequeue(); return(scheduledTask); } return(null); }
protected SingleThreadEventExecutor(IEventExecutorGroup parent, string threadName, TimeSpan breakoutInterval, IQueue <IRunnable> taskQueue) : base(parent) { this.terminationCompletionSource = new TaskCompletionSource(); this.taskQueue = taskQueue; this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval); this.scheduler = new ExecutorTaskScheduler(this); this.thread = new Thread(this.Loop); if (string.IsNullOrEmpty(threadName)) { this.thread.Name = DefaultWorkerThreadName; } else { this.thread.Name = threadName; } this.thread.Start(); }
private bool RunAllTasks(PreciseTimeSpan timeout) { _ = FetchFromScheduledTaskQueue(); IRunnable task = PollTask(); if (task is null) { AfterRunningAllTasks(); return(false); } PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout); long runTasks = 0; PreciseTimeSpan executionTime; while (true) { SafeExecute(task); runTasks++; // Check timeout every 64 tasks because nanoTime() is relatively expensive. // XXX: Hard-coded value - will make it configurable if it is really a problem. if (0ul >= (ulong)(runTasks & 0x3F)) { executionTime = PreciseTimeSpan.FromStart; if (executionTime >= deadline) { break; } } task = PollTask(); if (task is null) { executionTime = PreciseTimeSpan.FromStart; break; } } AfterRunningAllTasks(); _lastExecutionTime = executionTime; return(true); }
public SingleThreadEventExecutor(string threadName, TimeSpan breakoutInterval) { this.terminationCompletionSource = new TaskCompletionSource(); this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval); this.scheduler = new ExecutorTaskScheduler(this); this.thread = new Thread(this.Loop) { IsBackground = true }; if (string.IsNullOrEmpty(threadName)) { this.thread.Name = DefaultWorkerThreadName; } else { this.thread.Name = threadName; } this.thread.Start(); }
protected SingleThreadEventExecutor(IEventExecutorGroup parent, string threadName, TimeSpan breakoutInterval, IQueue <IRunnable> taskQueue) : base(parent) { _loopAction = Loop; _loopCoreAciton = LoopCore; _terminationCompletionSource = NewPromise(); _taskQueue = taskQueue; _preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval); _scheduler = new ExecutorTaskScheduler(this); _thread = new Thread(_loopAction); if (string.IsNullOrEmpty(threadName)) { _thread.Name = DefaultWorkerThreadName; } else { _thread.Name = threadName; } _thread.Start(); }
protected bool RunAllTasks() { this.FetchFromScheduledTaskQueue(); IRunnable task = this.PollTask(); if (task == null) { return(false); } while (true) { SafeExecute(task); task = this.PollTask(); if (task == null) { this.lastExecutionTime = PreciseTimeSpan.FromStart; return(true); } } }
private bool FetchFromScheduledTaskQueue() { if (ScheduledTaskQueue.IsEmpty) { return(true); } PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; IScheduledRunnable scheduledTask = PollScheduledTask(nanoTime); while (scheduledTask is object) { if (!_taskQueue.TryEnqueue(scheduledTask)) { // No space left in the task queue add it back to the scheduledTaskQueue so we pick it up again. _ = ScheduledTaskQueue.TryEnqueue(scheduledTask); return(false); } scheduledTask = PollScheduledTask(nanoTime); } return(true); }
protected bool RunAllTasks() { this.FetchFromScheduledTaskQueue(); IRunnable task = this.PollTask(); if (task == null) { return(false); } while (true) { Volatile.Write(ref this.progress, this.progress + 1); // volatile write is enough as this is the only thread ever writing SafeExecute(task); task = this.PollTask(); if (task == null) { this.lastExecutionTime = PreciseTimeSpan.FromStart; return(true); } } }
/// <summary> /// Tries to query measured process times. /// </summary> /// <param name="ptr">Process handle.</param> /// <param name="processTimes">Measured process times.</param> /// <returns>True if received the process times.</returns> internal static bool TryGetProcessTimes(IntPtr ptr, out ProcessTimes processTimes) { processTimes = new ProcessTimes(); System.Runtime.InteropServices.ComTypes.FILETIME lpCreationTime, lpExitTime, lpKernel, lpUser; bool result = GetProcessTimes(ptr, out lpCreationTime, out lpExitTime, out lpKernel, out lpUser); if (!result) { Console.Error.WriteLine("Unable to query process time."); return(false); } DateTime creation = DateTime.FromFileTime(ComFileTimeToTicks(lpCreationTime)); DateTime exit = DateTime.FromFileTime(ComFileTimeToTicks(lpExitTime)); processTimes = new ProcessTimes(PreciseTimeSpan.FromTicks((exit - creation).Ticks), PreciseTimeSpan.FromTicks(ComFileTimeToTicks(lpUser)), PreciseTimeSpan.FromTicks(ComFileTimeToTicks(lpKernel))); return(true); }
public LoopExecutor(IEventLoopGroup parent, string threadName, TimeSpan breakoutInterval) : base(parent) { this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval); this.preciseTimerInterval = PreciseTimeSpan.FromTimeSpan(TimeSpan.FromTicks(breakoutInterval.Ticks * 2)); this.terminationCompletionSource = new TaskCompletionSource(); this.taskQueue = PlatformDependent.NewMpscQueue <IRunnable>(); this.scheduler = new ExecutorTaskScheduler(this); this.loop = new Loop(); this.asyncHandle = new Async(this.loop, RunAllTasksCallback, this); this.timerHandle = new Timer(this.loop, RunAllTasksCallback, this); string name = string.Format(DefaultWorkerThreadName, this.loop.Handle); if (!string.IsNullOrEmpty(threadName)) { name = $"{name} ({threadName})"; } this.thread = new XThread(RunLoop) { Name = name }; }
public override bool WaitTermination(TimeSpan timeout) { PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout); for (int i = 0; i < _eventLoops.Length; i++) { var executor = _eventLoops[i]; for (; ;) { PreciseTimeSpan timeLeft = deadline - PreciseTimeSpan.FromStart; if (timeLeft <= PreciseTimeSpan.Zero) { goto LoopEnd; } if (executor.WaitTermination(timeLeft.ToTimeSpan())) { break; } } } LoopEnd: return(IsTerminated); }
protected ScheduledAsyncTask(AbstractScheduledEventExecutor executor, PreciseTimeSpan deadline, TaskCompletionSource promise, CancellationToken cancellationToken) : base(executor, deadline, promise) { this.cancellationToken = cancellationToken; this.cancellationTokenRegistration = cancellationToken.Register(s => ((ScheduledAsyncTask)s).Cancel(), this); }
public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan timeout) { Contract.Requires(quietPeriod >= TimeSpan.Zero); Contract.Requires(timeout >= quietPeriod); if (this.IsShuttingDown) { return(this.TerminationCompletion); } bool inEventLoop = this.InEventLoop; bool wakeup; int oldState; while (true) { if (this.IsShuttingDown) { return(this.TerminationCompletion); } int newState; wakeup = true; oldState = this.executionState; if (inEventLoop) { newState = ST_SHUTTING_DOWN; } else { switch (oldState) { case ST_NOT_STARTED: case ST_STARTED: newState = ST_SHUTTING_DOWN; break; default: newState = oldState; wakeup = false; break; } } if (Interlocked.CompareExchange(ref this.executionState, newState, oldState) == oldState) { break; } } this.gracefulShutdownQuietPeriod = PreciseTimeSpan.FromTimeSpan(quietPeriod); this.gracefulShutdownTimeout = PreciseTimeSpan.FromTimeSpan(timeout); // todo: revisit //if (oldState == ST_NOT_STARTED) //{ // scheduleExecution(); //} //if (wakeup) //{ // wakeup(inEventLoop); //} return(this.TerminationCompletion); }
bool RunAllTasks(PreciseTimeSpan timeout) { this.FetchFromScheduledTaskQueue(); IRunnable task = this.PollTask(); if (task == null) { return false; } PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout); long runTasks = 0; PreciseTimeSpan executionTime; while (true) { try { task.Run(); } catch (Exception ex) { Logger.Warn("A task raised an exception.", ex); } runTasks++; // Check timeout every 64 tasks because nanoTime() is relatively expensive. // XXX: Hard-coded value - will make it configurable if it is really a problem. if ((runTasks & 0x3F) == 0) { executionTime = PreciseTimeSpan.FromStart; if (executionTime >= deadline) { break; } } task = this.PollTask(); if (task == null) { executionTime = PreciseTimeSpan.FromStart; break; } } this.lastExecutionTime = executionTime; return true; }
protected bool RunAllTasks() { this.FetchFromScheduledTaskQueue(); IRunnable task = this.PollTask(); if (task == null) { return false; } while (true) { try { task.Run(); } catch (Exception ex) { Logger.Warn("A task raised an exception.", ex); } task = this.PollTask(); if (task == null) { this.lastExecutionTime = PreciseTimeSpan.FromStart; return true; } } }
public StateActionScheduledTask(AbstractScheduledEventExecutor executor, Action<object> action, object state, PreciseTimeSpan deadline) : base(executor, deadline, new TaskCompletionSource(state)) { this.action = action; }
public override Task ScheduleAsync(Action <object, object> action, object context, object state, TimeSpan delay, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(TaskEx.Cancelled); } if (!cancellationToken.CanBeCanceled) { return(this.Schedule(action, context, state, delay).Completion); } return(this.Schedule(new StateActionWithContextScheduledAsyncTask(this, action, context, state, PreciseTimeSpan.Deadline(delay), cancellationToken)).Completion); }
public override IScheduledTask Schedule(Action action, TimeSpan delay) { Contract.Requires(action != null); return(this.Schedule(new ActionScheduledTask(this, action, PreciseTimeSpan.Deadline(delay)))); }
protected ScheduledTask(AbstractScheduledEventExecutor executor, PreciseTimeSpan deadline, TaskCompletionSource promise) { this.Executor = executor; this.Promise = promise; this.Deadline = deadline; }
public StateActionScheduledTask(Action <object> action, object state, PreciseTimeSpan deadline, CancellationToken cancellationToken) : base(deadline, new TaskCompletionSource(state), cancellationToken) { this.action = action; }
public RunnableScheduledTask(AbstractScheduledEventExecutor executor, IRunnable action, PreciseTimeSpan deadline) : base(executor, deadline, new TaskCompletionSource()) { this.action = action; }
protected ScheduledTaskBase(PreciseTimeSpan deadline, TaskCompletionSource promise, CancellationToken cancellationToken) { this.promise = promise; this.Deadline = deadline; this.CancellationToken = cancellationToken; }
public override Task ScheduleAsync(Action <object, object> action, object context, object state, TimeSpan delay, CancellationToken cancellationToken) { var scheduledTask = new StateActionWithContextScheduledTask(action, context, state, PreciseTimeSpan.Deadline(delay), cancellationToken); if (this.InEventLoop) { this.ScheduledTaskQueue.Enqueue(scheduledTask); } else { this.Execute(AddScheduledTaskAction, this, scheduledTask); } return(scheduledTask.Completion); }
public StateActionScheduledTask(AbstractScheduledEventExecutor executor, Action <object> action, object state, PreciseTimeSpan deadline) : base(executor, deadline, new TaskCompletionSource(state)) { this.action = action; }
Task PublishReleaseToClientAsync(IChannelHandlerContext context, int packetId, string lockToken, IQos2MessageDeliveryState messageState, PreciseTimeSpan startTimestamp) { var pubRelPacket = new PubRelPacket { PacketId = packetId }; return this.pubRelPubCompProcessor.SendRequestAsync(context, pubRelPacket, new CompletionPendingMessageState(packetId, lockToken, messageState, startTimestamp)); }
public ActionScheduledAsyncTask(AbstractScheduledEventExecutor executor, Action action, PreciseTimeSpan deadline, CancellationToken cancellationToken) : base(executor, deadline, new TaskCompletionSource(), cancellationToken) { this.action = action; }
public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan timeout) { Contract.Requires(quietPeriod >= TimeSpan.Zero); Contract.Requires(timeout >= quietPeriod); if (this.IsShuttingDown) { return this.TerminationCompletion; } bool inEventLoop = this.InEventLoop; bool wakeup; int oldState; while (true) { if (this.IsShuttingDown) { return this.TerminationCompletion; } int newState; wakeup = true; oldState = this.executionState; if (inEventLoop) { newState = ST_SHUTTING_DOWN; } else { switch (oldState) { case ST_NOT_STARTED: case ST_STARTED: newState = ST_SHUTTING_DOWN; break; default: newState = oldState; wakeup = false; break; } } if (Interlocked.CompareExchange(ref this.executionState, newState, oldState) == oldState) { break; } } this.gracefulShutdownQuietPeriod = PreciseTimeSpan.FromTimeSpan(quietPeriod); this.gracefulShutdownTimeout = PreciseTimeSpan.FromTimeSpan(timeout); // todo: revisit //if (oldState == ST_NOT_STARTED) //{ // scheduleExecution(); //} //if (wakeup) //{ // wakeup(inEventLoop); //} return this.TerminationCompletion; }
public override IScheduledTask Schedule(Action <object, object> action, object context, object state, TimeSpan delay) { Contract.Requires(action != null); return(this.Schedule(new StateActionWithContextScheduledTask(this, action, context, state, PreciseTimeSpan.Deadline(delay)))); }
protected bool ConfirmShutdown() { if (!this.IsShuttingDown) { return false; } if (!this.InEventLoop) { throw new InvalidOperationException("must be invoked from an event loop"); } this.CancelScheduledTasks(); if (this.gracefulShutdownStartTime == PreciseTimeSpan.Zero) { this.gracefulShutdownStartTime = PreciseTimeSpan.FromStart; } if (this.RunAllTasks()) // || runShutdownHooks()) { if (this.IsShutdown) { // Executor shut down - no new tasks anymore. return true; } // There were tasks in the queue. Wait a little bit more until no tasks are queued for the quiet period. // todo: ??? //wakeup(true); return false; } PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart; if (this.IsShutdown || nanoTime - this.gracefulShutdownStartTime > this.gracefulShutdownTimeout) { return true; } if (nanoTime - this.lastExecutionTime <= this.gracefulShutdownQuietPeriod) { // Check if any tasks were added to the queue every 100ms. // TODO: Change the behavior of takeTask() so that it returns on timeout. // todo: ??? //wakeup(true); Thread.Sleep(100); return false; } // No tasks were added for last quiet period - hopefully safe to shut down. // (Hopefully because we really cannot make a guarantee that there will be no execute() calls by a user.) return true; }
public ActionScheduledTask(Action action, PreciseTimeSpan deadline, CancellationToken cancellationToken) : base(deadline, new TaskCompletionSource(), cancellationToken) { this.action = action; }