# HG changeset patch
# User cin
# Date 1523636099 -10800
# Node ID 547a2fc0d93ea5f867c778d7eeaa5888cc24fb9e
# Parent  7d52dc684bbdb3546070a49b9e7f3b58359c3b68
minor fixes
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Playground/Implab.Playground.csproj
--- a/Implab.Playground/Implab.Playground.csproj	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab.Playground/Implab.Playground.csproj	Fri Apr 13 19:14:59 2018 +0300
@@ -1,69 +1,20 @@
-
-
-  
-  
-    Debug
-    AnyCPU
-    {100DFEB0-75BE-436F-ADDF-1F46EF433F46}
-    Exe
-    Properties
-    Implab.Playground
-    Implab.Playground
-    v4.6
-    512
-    true
-    
+
+  
+    netcoreapp2.0;net46
+    /usr/lib/mono/4.6-api/
   
-  
-    AnyCPU
-    true
-    full
-    false
-    bin\Debug\
-    DEBUG;TRACE
-    prompt
-    4
+
+  
+    netcoreapp2.0;net46
   
-  
-    AnyCPU
-    pdbonly
-    true
-    bin\Release\
-    TRACE
-    prompt
-    4
-    true
-    true
+
+  
+    Exe
+    false
   
-  
-    
-    
-    
-    
-    
-    
-    
-    
-  
+
   
-    
-    
-  
-  
-    
+    
   
-  
-    
-      {f550f1f8-8746-4ad0-9614-855f4c4b7f05}
-      Implab
-    
-  
-  
-  
-
\ No newline at end of file
+  
+
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Playground/Program.cs
--- a/Implab.Playground/Program.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab.Playground/Program.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -15,7 +15,6 @@
 
 namespace Implab.Playground {
     using System.Diagnostics;
-    using System.Runtime.Remoting.Messaging;
     using static Trace;
 
     public class Program {
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Playground/Properties/AssemblyInfo.cs
--- a/Implab.Playground/Properties/AssemblyInfo.cs	Fri Apr 13 03:57:39 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Implab.Playground")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Implab.Playground")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("100dfeb0-75be-436f-addf-1f46ef433f46")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Test/Implab.Test.csproj
--- a/Implab.Test/Implab.Test.csproj	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab.Test/Implab.Test.csproj	Fri Apr 13 19:14:59 2018 +0300
@@ -1,8 +1,14 @@
 
+  
+    netcoreapp2.0
+    /usr/lib/mono/4.5/
+  
+
+  
+    netcoreapp2.0;net46
+  
 
   
-    netcoreapp2.1
-
     false
   
 
@@ -13,5 +19,5 @@
     
     
   
-
+  
 
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Test/MockPollComponent.cs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.Test/MockPollComponent.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -0,0 +1,35 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Implab.Components;
+
+namespace Implab.Test {
+    public class MockPollComponent : PollingComponent {
+
+        public Func PollWorker { get; set;}
+
+        public Func StartWorker { get; set; }
+
+        public Func StopWorker { get; set; }
+
+        public MockPollComponent(bool initialized) : base(initialized) {
+        }
+
+        protected async override Task Poll(CancellationToken ct) {
+            if(PollWorker!= null)
+                await PollWorker.Invoke(ct);
+        }
+
+        protected async override Task StopInternalAsync(CancellationToken ct) {
+            if (StopWorker != null)
+                await StopWorker.Invoke(ct);
+        }
+
+        protected async override Task StartInternalAsync(CancellationToken ct) {
+            if (StartWorker != null)
+                await StartWorker.Invoke(ct);
+        }
+
+
+    }
+}
\ No newline at end of file
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab.Test/RunnableComponentTests.cs
--- a/Implab.Test/RunnableComponentTests.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab.Test/RunnableComponentTests.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -4,38 +4,26 @@
 using Implab.Components;
 using Xunit;
 
-namespace Implab.Test
-{
-    class TimeLog : PollingComponent {
-        public TimeLog() : base(true) {
-        }
+namespace Implab.Test {
 
-        protected override Task Poll(CancellationToken ct) {
-            Console.WriteLine("Poll");
-            return Task.CompletedTask;
-        }
-    }
-
-    public class UnitTest1
-    {
+    public class RunnableComponentTests {
         [Fact]
-        public async Task Test1()
-        {
+        public async Task Test1() {
 
-            using(var  tl = new TimeLog()) {
-                tl.StateChanged += (self, args) => Console.WriteLine("{0}", args.State);
-                tl.Delay = 1000;
-                tl.Interval = 500;
+            using (var m = new MockPollComponent(true)) {
+                m.StartWorker = async (ct) => await Task.Yield();
+                m.StopWorker = async (ct) => await Task.Yield();
 
+                Assert.Equal(ExecutionState.Ready, m.State);
+                Assert.NotNull(m.Completion);
                 
-                tl.Start(CancellationToken.None);
-                await tl.Completion;
+                m.Start(CancellationToken.None);
+                await m.Completion;
+                Assert.Equal(ExecutionState.Running, m.State);
 
-                await Task.Delay(2000);
-
-                tl.Stop(CancellationToken.None);
-                await tl.Completion;
-                await Task.Delay(3000);
+                m.Stop(CancellationToken.None);
+                await m.Completion;
+                Assert.Equal(ExecutionState.Stopped, m.State);
             }
         }
     }
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab/Components/PollingComponent.cs
--- a/Implab/Components/PollingComponent.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab/Components/PollingComponent.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -50,7 +50,7 @@
             try {
                 // await for pending poll
                 await m_poll;
-            } catch (OperationCanceledException e) {
+            } catch (OperationCanceledException) {
                 // OK
             }
         }
@@ -71,12 +71,16 @@
             try {
                 m_pending.Start();
                 await m_poll;
+                ScheduleNextPoll(Interval);
             } catch (Exception e) {
                 UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false));
+
                 if (FailOnError)
                     Fail(e);
+                else
+                    ScheduleNextPoll(Interval);
             }
-            ScheduleNextPoll(Interval);
+            
         }
 
         protected override void Dispose(bool disposing) {
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab/Components/RunnableComponent.cs
--- a/Implab/Components/RunnableComponent.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab/Components/RunnableComponent.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -319,6 +319,7 @@
                     MoveSuccess(cookie);
                 } catch (Exception e) {
                     MoveFailed(e, cookie);
+                    throw;
                 }
             }, ct);
 
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab/Deferred.cs
--- a/Implab/Deferred.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab/Deferred.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -13,7 +13,7 @@
             m_promise = new Promise();
         }
 
-        internal Deferred(Promise promise, IDispatcher dispatcher) {
+        internal Deferred(Promise promise) {
             Debug.Assert(promise != null);
             m_promise = promise;
         }
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab/Implab.csproj
--- a/Implab/Implab.csproj	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab/Implab.csproj	Fri Apr 13 19:14:59 2018 +0300
@@ -8,9 +8,12 @@
     and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
     
     2012-2018 Sergey Smirnov
-    https://opensource.org/licenses/BSD-2-Clause
-    https://implab.org
+    3.0.6
+    https://opensource.org/licenses/BSD-2-Clause
+    https://implab.org
     https://hg.implab.org/pub/ImplabNet/
+    mercurial
+    IMPLAB;Json pull-parser;Json Xml;async;diagnostics;serialization;
     netstandard2.0;net46
     /usr/lib/mono/4.5/
     NETFX_TRACE_BUG;$(DefineConstants)
diff -r 7d52dc684bbd -r 547a2fc0d93e Implab/Promise.cs
--- a/Implab/Promise.cs	Fri Apr 13 03:57:39 2018 +0300
+++ b/Implab/Promise.cs	Fri Apr 13 19:14:59 2018 +0300
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Reflection;
+using System.Threading;
 using System.Threading.Tasks;
 using Implab.Parallels;
 
@@ -152,31 +153,44 @@
         }
 
         public static IPromise Create(PromiseExecutor executor) {
-            Safe.ArgumentNotNull(executor, nameof(executor));
+            return Create(executor, CancellationToken.None);
+        }
 
-            var p = new Promise();
-            var d = new Deferred(p, DefaultDispatcher);
-
+        public static IPromise Create(PromiseExecutor executor, CancellationToken ct) {
+            Safe.ArgumentNotNull(executor, nameof(executor));
+            if (!ct.CanBeCanceled)
+                return Create(executor);
+            
+            var d = new Deferred();
+            
+            ct.Register(d.Cancel);
+            
             try {
-                executor(d);
-            } catch (Exception e) {
+                if (!ct.IsCancellationRequested)
+                    executor(d);
+            } catch(Exception e) {
                 d.Reject(e);
             }
-
             return d.Promise;
         }
 
         public static IPromise Create(PromiseExecutor executor) {
+            return Create(executor, CancellationToken.None);
+        }
+
+        public static IPromise Create(PromiseExecutor executor, CancellationToken ct) {
             Safe.ArgumentNotNull(executor, nameof(executor));
 
             var d = new Deferred();
-
+            
+            ct.Register(d.Cancel);
+            
             try {
-                executor(d);
-            } catch (Exception e) {
+                if (!ct.IsCancellationRequested)
+                    executor(d);
+            } catch(Exception e) {
                 d.Reject(e);
             }
-
             return d.Promise;
         }