##// END OF EJS Templates
Working on runnable component
cin -
r250:9f63dade3a40 v3
parent child
Show More
@@ -0,0 +1,13
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Implab.Components {
8 public interface IServiceLocator: IServiceProvider {
9 T GetService<T>();
10 bool TryGetService<T>(out T service);
11 bool TryGetService (Type serviceType, out object service);
12 }
13 }
@@ -0,0 +1,57
1 using System;
2 using System.Threading;
3 using System.Threading.Tasks;
4
5 namespace Implab.Components
6 {
7 public class RunnableComponent : IRunnable {
8
9 readonly object m_lock = new object();
10
11 CancellationTokenSource m_cts;
12
13 public Task<ExecutionState> Completion {
14 get;
15 private set;
16 }
17
18 public ExecutionState State => throw new NotImplementedException();
19
20 public Exception LastError => throw new NotImplementedException();
21
22 public event EventHandler<StateChangeEventArgs> StateChanged;
23
24 public void Dispose() {
25 lock(m_lock) {
26 Dispose(true);
27 GC.SuppressFinalize(this);
28 }
29 }
30
31 protected virtual void Dispose(bool disposing) {
32 if (disposing) {
33 Safe.Dispose(m_cts);
34 }
35 }
36
37 public void Start(CancellationToken ct) {
38 lock(m_lock) {
39 switch (State)
40 {
41
42 default:
43 throw new InvalidOperationException();
44 }
45 }
46 }
47
48 public void Stop(CancellationToken ct) {
49 throw new NotImplementedException();
50 }
51
52 protected virtual Task StartImpl(CancellationToken ct) {
53
54 return Task.CompletedTask;
55 }
56 }
57 } No newline at end of file
@@ -0,0 +1,10
1 using System.Threading;
2 using System.Threading.Tasks;
3
4 namespace Implab.Messaging {
5 public interface IConsumer<T> {
6 Task<T> Receive(CancellationToken ct);
7
8 bool TryReceive(out T message);
9 }
10 } No newline at end of file
@@ -0,0 +1,11
1 using System.Collections.Generic;
2 using System.Threading;
3 using System.Threading.Tasks;
4
5 namespace Implab.Messaging {
6 public interface IProducer<T> {
7 Task PostMessageAsync(T message, CancellationToken ct);
8
9 Task PostMessagesAsync(IEnumerable<T> messages, CancellationToken ct);
10 }
11 } No newline at end of file
@@ -1,103 +1,63
1 using Implab.Diagnostics;
1 using Implab.Diagnostics;
2 using System;
2 using System;
3 using System.Diagnostics.CodeAnalysis;
3 using System.Diagnostics.CodeAnalysis;
4 using System.Threading;
4 using System.Threading;
5
5
6 namespace Implab.Components {
6 namespace Implab.Components {
7 /// <summary>
7 /// <summary>
8 /// Base class the objects which support disposing.
8 /// Base class the objects which support disposing.
9 /// </summary>
9 /// </summary>
10 public class Disposable : IDisposable {
10 public class Disposable : IDisposable {
11
11
12 int m_disposed;
13
14 public event EventHandler Disposed;
12 public event EventHandler Disposed;
15
13
16 public bool IsDisposed {
14 public bool IsDisposed {
17 get {
15 get; private set;
18 Thread.MemoryBarrier();
19 return m_disposed != 0;
20 }
21 }
16 }
22
17
23 /// <summary>
18 /// <summary>
24 /// Asserts the object is not disposed.
19 /// Asserts the object is not disposed.
25 /// </summary>
20 /// </summary>
26 /// <exception cref="ObjectDisposedException">The object is disposed</exception>
21 /// <exception cref="ObjectDisposedException">The object is disposed</exception>
27 /// <remarks>
22 /// <remarks>
28 /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не
29 /// будет освобожден сразу после нее, поэтому методы использующие проверку должны
30 /// учитывать, что объект может быть освобожден из параллельного потока.
31 /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его
32 /// освобождения.
33 /// </remarks>
34 /// <example>
35 /// // пример синхронизированного освобождения ресурсов
36 /// class FileStore : Disposable {
37 /// readonly TextWriter m_file;
38 /// readonly obejct m_sync = new object();
39 ///
40 /// public FileStore(string file) {
41 /// m_file = new TextWriter(File.OpenWrite(file));
42 /// }
43 ///
44 /// public void Write(string text) {
45 /// lock(m_sync) {
46 /// AssertNotDisposed();
47 /// m_file.Write(text);
48 /// }
49 /// }
50 ///
51 /// protected override void Dispose(bool disposing) {
52 /// if (disposing)
53 /// lock(m_sync) {
54 /// m_file.Dipose();
55 /// base.Dispose(true);
56 /// }
57 /// else
58 /// base.Dispose(false);
59 /// }
60 /// }
61 /// <example>
62 protected void AssertNotDisposed() {
23 protected void AssertNotDisposed() {
63 Thread.MemoryBarrier();
24 if (IsDisposed)
64 if (m_disposed != 0)
65 throw new ObjectDisposedException(ToString());
25 throw new ObjectDisposedException(ToString());
66 }
26 }
67 /// <summary>
27 /// <summary>
68 /// Вызывает событие <see cref="Disposed"/>
28 /// Вызывает событие <see cref="Disposed"/>
69 /// </summary>
29 /// </summary>
70 /// <param name="disposing">Признак того, что нужно освободить ресурсы, иначе данный метод
30 /// <param name="disposing">Признак того, что нужно освободить ресурсы, иначе данный метод
71 /// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого
31 /// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого
72 /// объекта.</param>
32 /// объекта.</param>
73 /// <remarks>
33 /// <remarks>
74 /// Данный метод вызывается гарантированно один раз даже при одновременном вызове <see cref="Dispose()"/>
34 /// Данный метод вызывается гарантированно один раз даже при одновременном вызове <see cref="Dispose()"/>
75 /// из нескольких потоков.
35 /// из нескольких потоков.
76 /// </remarks>
36 /// </remarks>
77 protected virtual void Dispose(bool disposing) {
37 protected virtual void Dispose(bool disposing) {
78 if (disposing)
38 if (disposing)
79 Disposed.DispatchEvent(this, EventArgs.Empty);
39 Disposed.DispatchEvent(this, EventArgs.Empty);
80
81 }
40 }
82
41
83 [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")]
42 [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")]
84 public void Dispose() {
43 public void Dispose() {
85 if (Interlocked.Increment(ref m_disposed) == 1) {
44 if(!IsDisposed) {
45 IsDisposed = true;
86 Dispose(true);
46 Dispose(true);
87 GC.SuppressFinalize(this);
47 GC.SuppressFinalize(this);
88 }
48 }
89 }
49 }
90
50
91 /// <summary>
51 /// <summary>
92 /// Записывает сообщение об утечке объекта.
52 /// Записывает сообщение об утечке объекта.
93 /// </summary>
53 /// </summary>
94 protected virtual void ReportObjectLeaks() {
54 protected virtual void ReportObjectLeaks() {
95 TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
55 TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
96 }
56 }
97
57
98 ~Disposable() {
58 ~Disposable() {
99 Dispose(false);
59 Dispose(false);
100 ReportObjectLeaks();
60 ReportObjectLeaks();
101 }
61 }
102 }
62 }
103 } No newline at end of file
63 }
@@ -1,30 +1,24
1 namespace Implab.Components {
1 namespace Implab.Components {
2
2
3 public enum ExecutionState {
3 public enum ExecutionState {
4 Undefined = 0,
4 Undefined = 0,
5
5
6 Created,
6 Created,
7
7
8 Initializing,
8 Initializing,
9
9
10 Ready,
10 Ready,
11
11
12 Starting,
12 Starting,
13
13
14 Running,
14 Running,
15
15
16 Suspending,
17
18 Suspended,
19
20 Resuming,
21
22 Stopping,
16 Stopping,
23
17
24 Failed,
18 Failed,
25
19
26 Disposed,
20 Disposed,
27
21
28 Last = Disposed
22 Last = Disposed
29 }
23 }
30 } No newline at end of file
24 }
@@ -1,21 +1,21
1 using System;
1 using System;
2
2
3 namespace Implab.Components {
3 namespace Implab.Components {
4 /// <summary>
4 /// <summary>
5 /// Initializable components are created and initialized in two steps, first we have create the component,
5 /// Initializable components are created and initialized in two steps, first we have create the component,
6 /// then we have to complete it's creation by calling an <see cref="Initialize()"/> method. All parameters needed
6 /// then we have to complete it's creation by calling an <see cref="Initialize()"/> method. All parameters needed
7 /// to complete the initialization must be passed before the calling <see cref="Initialize()"/>
7 /// to complete the initialization must be passed before the calling <see cref="Initialize()"/>
8 /// </summary>
8 /// </summary>
9 public interface IInitializable {
9 public interface IInitializable {
10 /// <summary>
10 /// <summary>
11 /// Completes initialization.
11 /// Completes initialization.
12 /// </summary>
12 /// </summary>
13 /// <remarks>
13 /// <remarks>
14 /// Normally virtual methods shouldn't be called from the constructor, due to the incomplete object state, but
14 /// Normally virtual methods shouldn't be called from the constructor, due to the incomplete object state, but
15 /// they can be called from this method. This method is aьуерщlso usefull when we constructing a complex grpah
15 /// they can be called from this method. This method is also usefull when we constructing a complex grpah
16 /// of components where cyclic references may take place.
16 /// of components where cyclic references may take place.
17 /// </remarks>
17 /// </remarks>
18 void Initialize();
18 void Initialize();
19 }
19 }
20 }
20 }
21
21
@@ -1,30 +1,29
1 using System;
1 using System;
2 using System.Threading;
3 using System.Threading.Tasks;
2
4
3 namespace Implab.Components {
5 namespace Implab.Components {
4 /// <summary>
6 /// <summary>
5 /// Interface for the component which performs a long running task.
7 /// Interface for the component which performs a long running task.
6 /// </summary>
8 /// </summary>
7 /// <remarks>
8 /// <para>The component also should implement <see cref="IDisposable"/> interface to be able to release used resources.</para>
9 /// <para>All methods of this interface must be a thread safe. If the operation is not applicable in the current state the
10 /// method should throw an exception and keep the current state unchanged.</para>
11 /// </remarks>
12 public interface IRunnable : IDisposable {
9 public interface IRunnable : IDisposable {
13 /// <summary>
10 /// <summary>
14 /// Starts this instance
11 /// Starts this instance
15 /// </summary>
12 /// </summary>
16 IPromise Start();
13 void Start(CancellationToken ct);
17
14
18 /// <summary>
15 /// <summary>
19 /// Stops this instance, after the instance is stopped it can move to Failed, Ready or Disposed state, in case with the last it can't be reused.
16 /// Stops this instance and releases all resources, after the instance is stopped it is moved to Disposed state and can't be reused.
20 /// </summary>
17 /// </summary>
21 IPromise Stop();
18 void Stop(CancellationToken ct);
19
20 Task<ExecutionState> Completion { get; }
22
21
23 ExecutionState State { get; }
22 ExecutionState State { get; }
24
23
25 event EventHandler<StateChangeEventArgs> StateChanged;
24 event EventHandler<StateChangeEventArgs> StateChanged;
26
25
27 Exception LastError { get; }
26 Exception LastError { get; }
28 }
27 }
29 }
28 }
30
29
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now