##// 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
@@ -9,15 +9,10 namespace Implab.Components {
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>
@@ -25,43 +20,8 namespace Implab.Components {
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>
@@ -77,12 +37,12 namespace Implab.Components {
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 }
@@ -13,12 +13,6
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,
@@ -12,7 +12,7 namespace Implab.Components {
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();
@@ -1,24 +1,23
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
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