annotate Implab/Components/PollingRunnableComponent.cs @ 202:2651cb9a4250 v2

Implemented PollingRunnableComponent
author cin
date Tue, 18 Oct 2016 01:03:49 +0300
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
202
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
1 using System;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
2 using System.Threading;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
3 using Implab.Diagnostics;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
4
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
5 namespace Implab.Components {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
6 public class PollingRunnableComponent : RunnableComponent {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
7 readonly Timer m_timer;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
8 readonly Func<Func<IPromise>, IPromise> m_dispatcher;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
9 readonly TimeSpan m_interval;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
10
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
11 int m_processing;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
12 Promise m_pending;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
13
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
14 protected PollingRunnableComponent(TimeSpan interval, Func<Func<IPromise>, IPromise> dispatcher, bool initialized) : base(initialized) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
15 m_timer = new Timer(OnInternalTick);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
16
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
17 m_interval = interval;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
18 m_dispatcher = dispatcher;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
19 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
20
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
21 protected override IPromise OnStart() {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
22 m_timer.Change(TimeSpan.Zero, m_interval);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
23
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
24 return base.OnStart();
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
25 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
26
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
27 void OnInternalTick(object state) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
28 if (StartTick()) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
29 try {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
30 AwaitTick(m_dispatcher != null ? m_dispatcher(OnTick) : OnTick());
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
31 } catch (Exception error) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
32 HandleTickError(error);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
33 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
34 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
35 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
36
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
37 /// <summary>
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
38 /// Starts the tick handler.
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
39 /// </summary>
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
40 /// <returns>boolean value, true - the new tick handler may be invoked, false - a tick handler is already running or a component isn't running.</returns>
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
41 /// <remarks>
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
42 /// If the component is stopping no new handlers can be run. Every successful call to this method must be completed with either AwaitTick or HandleTickError handlers.
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
43 /// </remarks>
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
44 protected virtual bool StartTick() {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
45 if (State == ExecutionState.Running && Interlocked.CompareExchange(ref m_processing, 1, 0) == 0) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
46 m_pending = new Promise();
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
47 m_pending
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
48 .On(() => m_processing = 0, PromiseEventType.All)
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
49 .On(null, LogTickError);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
50 return true;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
51 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
52 return false;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
53 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
54
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
55 protected virtual void AwaitTick(IPromise tick) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
56 if (tick == null) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
57 m_pending.Resolve();
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
58 } else {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
59 tick.On(
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
60 m_pending.Resolve,
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
61 m_pending.Reject,
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
62 m_pending.CancelOperation
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
63 );
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
64 m_pending.CancellationRequested(tick.Cancel);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
65 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
66 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
67
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
68 protected virtual void HandleTickError(Exception error) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
69 m_pending.Reject(error);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
70 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
71
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
72 protected virtual void LogTickError(Exception error) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
73 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
74
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
75 protected virtual IPromise OnTick() {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
76 return Promise.SUCCESS;
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
77 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
78
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
79 protected override IPromise OnStop() {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
80 m_timer.Change(-1, -1);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
81
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
82 if (m_pending != null) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
83 m_pending.Cancel();
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
84 return m_pending.Then(base.OnStop);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
85 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
86
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
87 return base.OnStop();
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
88 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
89
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
90 protected override void Dispose(bool disposing, Exception lastError) {
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
91 if (disposing)
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
92 Safe.Dispose(m_timer);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
93
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
94 base.Dispose(disposing, lastError);
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
95 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
96 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
97 }
2651cb9a4250 Implemented PollingRunnableComponent
cin
parents:
diff changeset
98