示例#1
0
文件: Program.cs 项目: kenkendk/cocol
        public async Task RunAsync()
        {
            // Do warmup rounds
            for (var i = 0L; i < WARMUP; i++)
            {
                await m_channel.ReadAsync();
            }

            Console.WriteLine("Warmup complete, measuring");

            for (int r = 0; r < REPEATS; r++)
            {
                // Measure the run
                var start = DateTime.Now;
                for (var i = 0L; i < ROUNDS; i++)
                {
                    await m_channel.ReadAsync();
                }
                var finish = DateTime.Now;

                // Report
                Console.WriteLine("Time per iteration: {0} microseconds", ((finish - start).TotalMilliseconds * 1000) / ROUNDS);
                Console.WriteLine("Time per communication: {0} microseconds", ((finish - start).TotalMilliseconds * 1000) / ROUNDS / 4);
            }

            // Cleanup
            m_channel.Retire();
        }
示例#2
0
        /// <summary>
        /// Runs a repeated parallel operation
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="source">The channel where requests are read from</param>
        /// <param name="handler">The method to invoke for each item</param>
        /// <param name="token">Token.</param>
        /// <param name="maxparallel">The maximum parallelism to use.</param>
        /// <param name="errorHandler">The error handler</param>
        /// <typeparam name="T">The type of data elements to handle</typeparam>
        public static Task RunParallelAsync <T>(IReadChannel <T> source, Func <T, Task> handler, System.Threading.CancellationToken token, int maxparallel = 10, Func <T, Exception, Task> errorHandler = null)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (maxparallel <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxparallel), maxparallel, "The size of the queue must be greater than zero");
            }

            return(AutomationExtensions.RunTask(
                       new
            {
                Requests = source
            },
                       async self =>
            {
                using (var tp = new TaskPool <T>(maxparallel, errorHandler))
                    while (true)
                    {
                        if (token.IsCancellationRequested)
                        {
                            throw new TaskCanceledException();
                        }
                        await tp.Run(await source.ReadAsync(), handler).ConfigureAwait(false);
                    }
            }));
        }
示例#3
0
        /// <summary>
        /// Reads the channel in a probing and asynchronous manner
        /// </summary>
        /// <param name="self">The channel to read from</param>
        /// <param name="waittime">The amount of time to wait before cancelling</param>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        /// <returns>True if the read succeeded, false otherwise</returns>
        public static Task <KeyValuePair <bool, T> > TryReadAsync <T>(this IReadChannel <T> self, TimeSpan waittime)
        {
            return(self.ReadAsync(new TimeoutOffer(waittime)).ContinueWith(x => {
                if (x.IsFaulted || x.IsCanceled)
                {
                    return new KeyValuePair <bool, T>(false, default(T));
                }

                return new KeyValuePair <bool, T>(true, x.Result);
            }));
        }
示例#4
0
        /// <summary>
        /// Reads the channel in a probing and asynchronous manner
        /// </summary>
        /// <param name="self">The channel to read from</param>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        /// <returns>True if the read succeeded, false otherwise</returns>
        public static Task <KeyValuePair <bool, T> > TryReadAsync <T>(this IReadChannel <T> self)
        {
            return(self.ReadAsync(Timeout.Immediate, null).ContinueWith(x => {
                if (x.IsFaulted || x.IsCanceled)
                {
                    return new KeyValuePair <bool, T>(false, default(T));
                }

                return new KeyValuePair <bool, T>(true, x.Result);
            }));
        }
示例#5
0
        /// <summary>
        /// Read from the channel in a probing manner
        /// </summary>
        /// <param name="self">The channel to read from</param>
        /// <param name="result">The read result</param>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        /// <returns>True if the read succeeded, false otherwise</returns>
        public static bool TryRead <T>(this IReadChannel <T> self, out T result)
        {
            var res = self.ReadAsync(new TimeoutOffer(Timeout.Immediate)).WaitForTask();

            if (res.IsFaulted || res.IsCanceled)
            {
                result = default(T);
                return(false);
            }
            else
            {
                result = res.Result;
                return(true);
            }
        }
示例#6
0
文件: Program.cs 项目: bbants/cocol
 /// <summary>
 /// Runs the identity process, which simply forwards a value.
 /// </summary>
 /// <param name="chan_read">The channel to read from</param>
 /// <param name="chan_write">The channel to write to</param>
 private static async void RunIdentity(IReadChannel <T> chan_read, IWriteChannel <T> chan_write)
 {
     try
     {
         while (true)
         {
             await chan_write.WriteAsync(await chan_read.ReadAsync());
         }
     }
     catch (RetiredException)
     {
         chan_read.Retire();
         chan_write.Retire();
     }
 }
示例#7
0
 public async override Task RunAsync()
 {
     try
     {
         while (true)
         {
             await m_output.WriteAsync(await m_input.ReadAsync() + 1);
         }
     }
     catch (RetiredException)
     {
         m_input.Retire();
         m_output.Retire();
     }
 }
示例#8
0
文件: Prefix.cs 项目: Danstahr/cocol
		public async override Task RunAsync()
		{
			try
			{
				while(m_repeat-- > 0)
					await m_output.WriteAsync(m_value);
					
				while (true)
					await m_output.WriteAsync(await m_input.ReadAsync());
			}
			catch (RetiredException)
			{
				m_input.Retire();
				m_output.Retire();
			}
		}
示例#9
0
        /// <summary>
        /// Read from the channel in a blocking manner
        /// </summary>
        /// <param name="self">The channel to read from</param>
        /// <param name="timeout">The maximum time to wait for a value</param>
        /// <returns>>The value read from the channel</returns>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        public static T Read <T>(this IReadChannel <T> self, TimeSpan timeout)
        {
            try
            {
                return(self.ReadAsync(new TimeoutOffer(timeout)).WaitForTask().Result);
            }
            catch (AggregateException aex)
            {
                if (aex.Flatten().InnerExceptions.Count == 1)
                {
                    throw aex.InnerException;
                }

                throw;
            }
        }
示例#10
0
        /// <summary>
        /// A process that reads numbers and discards those that are
        /// divisible by a certain number and forwards the rest
        /// </summary>
        /// <returns>The awaitable task that represents the process</returns>
        /// <param name="number">The number used to test and filter divisible numbers with.</param>
        /// <param name="input">The channel where data is read from.</param>
        /// <param name="output">The channel where non-multiple values are written to.</param>
        private static async Task RunNoMultiplesAsync(long number, IReadChannel <long> input, IWriteChannel <long> output)
        {
            try
            {
                while (true)
                {
                    var v = await input.ReadAsync();

                    if (v % number != 0)
                    {
                        await output.WriteAsync(v);
                    }
                }
            }
            catch (RetiredException)
            {
                input.Retire();
                output.Retire();
            }
        }
示例#11
0
文件: Program.cs 项目: bbants/cocol
        /// <summary>
        /// Runs the delta process, which copies the value it reads onto two different channels
        /// </summary>
        /// <param name="chan_read">The channel to read from</param>
        /// <param name="chan_a">The channel to write to</param>
        /// <param name="chan_b">The channel to write to</param>
        private static async void RunDelta(IReadChannel <T> chan_read, IWriteChannel <T> chan_a, IWriteChannel <T> chan_b)
        {
            try
            {
                while (true)
                {
                    var value = await chan_read.ReadAsync();

                    await Task.WhenAll(
                        chan_a.WriteAsync(value),
                        chan_b.WriteAsync(value)
                        );
                }
            }
            catch (RetiredException)
            {
                chan_read.Retire();
                chan_a.Retire();
                chan_b.Retire();
            }
        }
示例#12
0
文件: Delta.cs 项目: bbants/cocol
        /// <summary>
        /// Runs the process.
        /// </summary>
        /// <returns>An awaitable task.</returns>
        public async override Task RunAsync()
        {
            try
            {
                while (true)
                {
                    var r = await m_input.ReadAsync();

                    await Task.WhenAll(
                        m_outputA.WriteAsync(r),
                        m_outputB.WriteAsync(r)
                        );
                }
            }
            catch (RetiredException)
            {
                m_input.Retire();
                m_outputA.Retire();
                m_outputB.Retire();
            }
        }
示例#13
0
        /// <summary>
        /// A process that spawns a new set of processes
        /// when a number is received.
        /// By inserting a NoMultiples into the chain,
        /// it is guaranteed that no numbers that are divisible
        /// with any number in the chain can be retrieved by the
        /// Sieve.
        /// </summary>
        /// <returns>The awaitable task that represents the process</returns>
        /// <param name="input">The channel to read numbers from</param>
        /// <param name="output">The channel to write numbers to</param>
        private static async Task RunSieveAsync(IReadChannel <long> input, IWriteChannel <long> output)
        {
            var chan = ChannelManager.CreateChannel <long>();

            try
            {
                var n = await input.ReadAsync();

                await output.WriteAsync(n);

                await Task.WhenAll(
                    RunNoMultiplesAsync(n, input, chan),
                    RunSieveAsync(chan, output)
                    );
            }
            catch (RetiredException)
            {
                chan.Retire();
                input.Retire();
                output.Retire();
            }
        }
示例#14
0
文件: Program.cs 项目: bbants/cocol
        /// <summary>
        /// Runs the delta process, which copies the value it reads onto two different channels
        /// </summary>
        /// <param name="chan_read">The channel to read from</param>
        /// <param name="chan_a">The channel to write to</param>
        /// <param name="chan_b">The channel to write to</param>
        private static async void RunDeltaAlt(IReadChannel <T> chan_read, IWriteChannel <T> chan_a, IWriteChannel <T> chan_b)
        {
            try
            {
                while (true)
                {
                    var value = await chan_read.ReadAsync();

                    var offer = new SingleOffer <T>();
                    await Task.WhenAll(
                        chan_a.WriteAsync(value),
                        chan_b.WriteAsync(value, CoCoL.Timeout.Infinite, offer)
                        );
                }
            }
            catch (RetiredException)
            {
                chan_read.Retire();
                chan_a.Retire();
                chan_b.Retire();
            }
        }
示例#15
0
        /// <summary>
        /// The runner helper method that calls the abstract request method
        /// </summary>
        /// <returns>An awaitable task</returns>
        protected Task RunAsync(IReadChannel <bool> reqchan, IWriteChannel <RequestResult> respchan)
        {
            return(AutomationExtensions.RunTask(
                       new { reqchan, respchan },
                       async _ =>
            {
                while (await reqchan.ReadAsync())
                {
                    var start = DateTime.Now;
                    try
                    {
                        var resp = await PeformRequestAsync();
                        await respchan.WriteAsync(new RequestResult()
                        {
                            Started = start,
                            Finished = DateTime.Now,
                            Failed = m_expectedresponse != null && m_expectedresponse != resp
                        });
                    }
                    catch (System.Exception ex)
                    {
                        await respchan.WriteAsync(new RequestResult()
                        {
                            Started = start,
                            Finished = DateTime.Now,
                            Failed = true,
                            Exception = ex
                        });

                        if (m_options.Verbose)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
            }));
        }
示例#16
0
 /// <summary>
 /// Reads the channel asynchronously
 /// </summary>
 /// <param name="self">The channel to read from</param>
 /// <typeparam name="T">The channel data type parameter.</typeparam>
 /// <returns>The value read from the channel</returns>
 public static Task <T> ReadAsync <T>(this IReadChannel <T> self)
 {
     return(self.ReadAsync(Timeout.Infinite, null));
 }
示例#17
0
        /// <summary>
        /// Runs a single peer connection, using the IPC link
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="self">This peer's information</param>
        /// <param name="remote">The remote peer's information</param>
        /// <param name="connecthandler">The method used to obtain the connection.</param>
        /// <param name="input">The channel for reading requests.</param>
        /// <param name="maxparallel">The maximum number of parallel handlers</param>
        private static async Task RunSingleConnection(PeerInfo self, PeerInfo remote, Func <Task <Stream> > connecthandler, IReadChannel <ConnectionRequest> input, int maxparallel)
        {
            // Get the local handler for remote requests
            var remotehandler = Channels.RemoteRequests.Get();

            LeanIPC.IPCPeer connection = null;

            try
            {
                if (connecthandler == null)
                {
                    throw new ArgumentNullException(nameof(connecthandler));
                }
                if (input == null)
                {
                    throw new ArgumentNullException(nameof(input));
                }

                log.Debug($"Setting up connection to {remote?.Key}");

                // Connect to the remote peer
                connection = new LeanIPC.IPCPeer(await connecthandler());

                // Setup a handler for remote requests, that forwards responses from the remote handler
                connection.AddUserTypeHandler <Protocol.Request>(
                    async(id, req) =>
                {
                    await connection.SendResponseAsync(id, (await remotehandler.SendConnectionRequestAsync(null, null, id, req)).Response);
                    return(true);
                }
                    );

                var mainTask  = connection.RunMainLoopAsync(self != remote);
                Key targetKey = null;

                // Grab a connection to update the routing table automatically
                var routingrequests = Channels.RoutingTableRequests.Get();

                log.Debug($"Peer connection running {self.Key}, {self.Address}");

                using (var tp = new TaskPool <ConnectionRequest>(maxparallel, (t, ex) => log.Warn("Unexpected error handling request", ex)))
                    while (true)
                    {
                        log.Debug($"Peer connection is waiting for request ...");

                        // Get either a local or a remote request
                        var req = await input.ReadAsync();

                        log.Debug($"Peer connection got request, handling on taskpool ...");

                        await tp.Run(req, () =>
                        {
                            log.Debug($"Peer connection is forwarding a local {req.Request.Operation} request to the remote");
                            return(Task.Run(async() =>
                            {
                                ConnectionResponse res;

                                try
                                {
                                    var p = await connection.SendAndWaitAsync <Protocol.Request, Protocol.Response>(req.Request);
                                    if (targetKey == null)
                                    {
                                        // Record the target key
                                        targetKey = p.Self.Key;
                                        if (remote == null || remote.Key == null)
                                        {
                                            remote = new PeerInfo(p.Self.Key, remote.Address);
                                        }

                                        // Write a registration request to the broker
                                        await Channels.ConnectionBrokerRegistrations.Get().WriteAsync(
                                            new ConnectionRegistrationRequest()
                                        {
                                            IsTerminate = false,
                                            UpdateRouting = true,
                                            Peer = remote
                                        }
                                            );

                                        log.Debug($"Registering peer in routing table: {remote.Key} {remote.Address} ...");
                                        await routingrequests.AddPeerAsync(remote.Key, remote);
                                    }

                                    if (p.Peers != null)
                                    {
                                        log.Debug($"Registering {p.Peers.Count} peers with the routing table ...");
                                        foreach (var peer in p.Peers)
                                        {
                                            await routingrequests.AddPeerAsync(peer.Key, peer);
                                        }

                                        log.Debug($"Registered {p.Peers.Count} peers with the routing table");
                                    }

                                    res = new ConnectionResponse()
                                    {
                                        Key = p.Self.Key,
                                        Response = p
                                    };
                                }
                                catch (Exception ex)
                                {
                                    log.Warn($"Failed to get result, sending error response", ex);
                                    res = new ConnectionResponse()
                                    {
                                        Key = targetKey,
                                        Exception = ex
                                    };

                                    log.Warn($"Killing peer due to the previous exception");
                                    await input.RetireAsync();
                                }

                                if (req.Response != null)
                                {
                                    try { await req.Response.WriteAsync(res); }
                                    catch (Exception ex) { log.Warn("Failed to send response", ex); }
                                }
                            }));
                        });
                    }
            }
            finally
            {
                await remotehandler.RetireAsync();

                if (connection != null)
                {
                    try { await connection.ShutdownAsync(); }
                    catch (Exception ex) { log.Warn("Failed to shut down IPC Peer", ex); }
                }

                // Write a registration request to the broker
                await Channels.ConnectionBrokerRegistrations.Get().WriteAsync(
                    new ConnectionRegistrationRequest()
                {
                    IsTerminate   = false,
                    UpdateRouting = false,
                    Peer          = remote
                }
                    );
            }
        }
示例#18
0
文件: Program.cs 项目: bbants/cocol
        /// <summary>
        /// Runs the tick collector process which measures the network performance
        /// </summary>
        /// <returns>The awaitable tick collector task.</returns>
        /// <param name="chan">The tick channel.</param>
        /// <param name="stop">The channel used to shut down the network.</param>
        private static async Task RunTickCollectorAsync(IReadChannel <T> chan, IChannel <T> stop, bool stop_after_tickcount)
        {
            var tickcount = 0;
            var rounds    = 0;

            //Initialize
            await chan.ReadAsync();

            var a_second = TimeSpan.FromSeconds(1).Ticks;

            //Warm up
            Console.WriteLine("Warming up ...");
            DateTime m_last = DateTime.Now;

            while (await chan.ReadAsync() != 0)
            {
                if ((DateTime.Now - m_last).Ticks > a_second)
                {
                    break;
                }
            }

            //Measuring
            Console.WriteLine("Measuring!");
            var measure_span = TimeSpan.FromSeconds(5).Ticks;

            m_last = DateTime.Now;

            try
            {
                while (await chan.ReadAsync() != 0)
                {
                    tickcount++;

                    bool round_complete;
                    if (stop_after_tickcount)
                    {
                        round_complete = tickcount >= Config.Ticks;
                    }
                    else
                    {
                        round_complete = (DateTime.Now - m_last).Ticks >= measure_span;
                    }

                    if (round_complete)
                    {
                        var duration = DateTime.Now - m_last;
                        Console.WriteLine("Got {0} ticks in {1} seconds, speed is {2} rounds/s ({3} msec/comm)", tickcount, duration, tickcount / duration.TotalSeconds, duration.TotalMilliseconds / ((tickcount) * Config.Processes));
                        Console.WriteLine("Time per iteration: {0} microseconds", (duration.TotalMilliseconds * 1000) / tickcount);
                        Console.WriteLine("Time per communication: {0} microseconds", (duration.TotalMilliseconds * 1000) / tickcount / 4);

                        tickcount = 0;
                        m_last    = DateTime.Now;

                        // For shutdown, we retire the initial channel
                        if (++rounds >= Config.MeasureCount)
                        {
                            stop.Retire();
                        }
                    }
                }
            }
            catch (RetiredException)
            {
                chan.Retire();
            }
        }
示例#19
0
 /// <summary>
 /// Reads the channel asynchronously.
 /// </summary>
 /// <returns>The task for awaiting completion.</returns>
 /// <param name="self">The channel to read.</param>
 /// <param name="timeout">The read timeout.</param>
 public static Task <T> ReadAsync <T>(this IReadChannel <T> self, TimeSpan timeout)
 {
     return(self.ReadAsync(new TimeoutOffer(timeout)));
 }
示例#20
0
 /// <summary>
 /// Reads the channel asynchronously.
 /// </summary>
 /// <returns>The task for awaiting completion.</returns>
 /// <param name="self">The channel to read.</param>
 /// <param name="cancelToken">The cancellation token</param>
 public static Task <T> ReadAsync <T>(this IReadChannel <T> self, CancellationToken cancelToken)
 {
     return(self.ReadAsync(new CancellationOffer(cancelToken)));
 }
示例#21
0
 /// <summary>
 /// Reads the channel asynchronously.
 /// </summary>
 /// <returns>The task for awaiting completion.</returns>
 /// <param name="self">The channel to read.</param>
 /// <param name="timeout">The read timeout.</param>
 /// <param name="cancelToken">The cancellation token</param>
 public static Task <T> ReadAsync <T>(this IReadChannel <T> self, TimeSpan timeout, CancellationToken cancelToken)
 {
     return(self.ReadAsync(new TimeoutOffer(timeout, cancelToken)));
 }