예제 #1
0
        public static Task RunGranterAsync(IWriteChannel <bool> channel, long count, CancellationToken token)
        {
            var canceltask = new TaskCompletionSource <bool>();

            token.Register(() => canceltask.TrySetCanceled());
            var total = count;

            return(AutomationExtensions.RunTask(
                       new { channel },

                       async self => {
                while (count > 0)
                {
                    DebugWriteLine($"Emitting task {total - count} of {total}");
                    if (await Task.WhenAny(new [] { canceltask.Task, channel.WriteAsync(true) }) == canceltask.Task)
                    {
                        throw new TaskCanceledException();
                    }

                    count--;
                    DebugWriteLine($"Emitted task {total - count} of {total}");
                }

                DebugWriteLine("Stopping task granter");
            }
                       ));
        }
예제 #2
0
파일: Prefix.cs 프로젝트: kenkendk/cocol
 /// <summary>
 /// Initializes a new instance of the <see cref="T:CoCoL.Blocks.Prefix`1"/> class.
 /// </summary>
 /// <param name="input">The input channel.</param>
 /// <param name="output">The output channel.</param>
 /// <param name="value">The initial value to emit.</param>
 /// <param name="repeat">The number of copies to initially emit.</param>
 public Prefix(IReadChannel <T> input, IWriteChannel <T> output, T value, long repeat = 1)
 {
     m_input  = input ?? throw new ArgumentNullException(nameof(input));
     m_output = output ?? throw new ArgumentNullException(nameof(output));
     m_value  = value;
     m_repeat = repeat;
 }
예제 #3
0
        /// <summary>
        /// Stores the value in long-term storage if required, and broadcasts the value,
        /// if we are the closest peer
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="self">The node's own information</param>
        /// <param name="router">The router request channel</param>
        /// <param name="key">The key for the data.</param>
        /// <param name="data">The data to store.</param>
        /// <param name="storechan">The channel pointing back to the store process</param>
        private static async Task StoreLongTermAsync(PeerInfo self, IWriteChannel <RoutingRequest> router, IWriteChannel <MRUInternalStore> storechan, Key key, byte[] data)
        {
            // We could use a small cache of peers here
            // to avoid hammering the routing process
            // for each insert

            log.Debug($"Checking if {key} should be inserted into long-term storage for {self.Key}");
            var list = await router.LookupPeerAsync(key, true);

            // If we are in the k-bucket closest peers, store it
            if (list.Any(x => self.Key.Equals(x.Key)))
            {
                // Check if we are the closest node
                var closest = self.Key.Equals(list.OrderBy(x => new KeyDistance(key, x.Key)).First().Key);

                log.Debug($"We are {(closest ? "*the* peer": "one of the peers")} for {key}");
                await storechan.WriteAsync(new MRUInternalStore()
                {
                    Key   = key,
                    Data  = data,
                    Peers = closest ? list : null
                });
            }
            else
            {
                log.Debug($"We are not one of the closest peers for {key}");
            }
        }
예제 #4
0
 /// <summary>
 /// Sends an expire request
 /// </summary>
 /// <returns>The result of the expire operation.</returns>
 /// <param name="channel">The request channel.</param>
 public static async Task <bool> SendExpireAsync(this IWriteChannel <MRURequest> channel)
 {
     return((await SendMessageAsync <MRURequest, MRUResponse>(channel, new MRURequest()
     {
         Operation = MRUOperation.Expire
     })).Success);
 }
예제 #5
0
파일: Program.cs 프로젝트: bbants/cocol
 /// <summary>
 /// Wraps the channel with a latency hiding instance, if required by config
 /// </summary>
 /// <returns>The buffered write channel.</returns>
 /// <param name="input">The input channel.</param>
 private static IWriteChannel <T> AsBufferedWrite(IWriteChannel <T> input)
 {
     if (Config.NetworkChannelLatencyBufferSize != 0 && input is NetworkChannel <T> && (Config.AllChannelsNetworked || ((INamedItem)input).Name == "tick"))
     {
         return(new LatencyHidingWriter <T>(input, Config.NetworkChannelLatencyBufferSize));
     }
     return(input);
 }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Duplicati.Library.UsageReporter.EventProcessor"/> class.
        /// </summary>
        /// <param name="forwardChannel">The forwarding destination.</param>
        public EventProcessor(IWriteChannel <string> forwardChannel)
        {
            INSTANCE_ID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();

            Channel    = m_channel = ChannelManager.CreateChannel <ReportItem>(null, MAX_QUEUE_SIZE);
            m_forward  = forwardChannel;
            Terminated = RunProtected(Run);
        }
예제 #7
0
 /// <summary>
 /// Wraps the channel with a latency hiding instance, if required by config
 /// </summary>
 /// <returns>The buffered write channel.</returns>
 /// <param name="input">The input channel.</param>
 private static IWriteChannel <T> AsBufferedWrite <T>(IWriteChannel <T> input)
 {
     if (Config.NetworkChannelLatencyBufferSize != 0 && input is NetworkChannel <T> && Config.NetworkedChannels)
     {
         return(new LatencyHidingWriter <T>(input, Config.NetworkChannelLatencyBufferSize));
     }
     return(input);
 }
예제 #8
0
 /// <summary>
 /// Removes the peer with the given key from the routing table.
 /// </summary>
 /// <returns>The peer to remove.</returns>
 /// <param name="channel">The channel to send the request on.</param>
 /// <param name="key">The key for the peer to remove.</param>
 public static Task RemovePeerAsync(this IWriteChannel <RoutingRequest> channel, Key key)
 {
     return(SendMessageAsync <RoutingRequest, RoutingResponse>(channel, new RoutingRequest()
     {
         Operation = RoutingOperation.Remove,
         Key = key
     }));
 }
예제 #9
0
 /// <summary>
 /// Adds a peer to the routing table
 /// </summary>
 /// <returns><c>true</c> if the peer is new, <c>false</c> otherwise.</returns>
 /// <param name="channel">The channel to send the request on.</param>
 /// <param name="key">The key for the peer.</param>
 /// <param name="peer">The peer.</param>
 public static async Task <bool> AddPeerAsync(this IWriteChannel <RoutingRequest> channel, Key key, PeerInfo peer)
 {
     return((await SendMessageAsync <RoutingRequest, RoutingResponse>(channel, new RoutingRequest()
     {
         Operation = RoutingOperation.Add,
         Key = key,
         Data = peer
     })).IsNew);
 }
예제 #10
0
 /// <summary>
 /// Looks up peers in the routing table
 /// </summary>
 /// <returns>The peers.</returns>
 /// <param name="channel">The channel to send the request on</param>
 /// <param name="onlyKbucket"><c>true</c> if the response must originate from the closest bucket, <c>false</c> otherwise.</param>
 /// <param name="key">The key to return the results for.</param>
 public static async Task <List <PeerInfo> > LookupPeerAsync(this IWriteChannel <RoutingRequest> channel, Key key, bool onlyKbucket = false)
 {
     return((await SendMessageAsync <RoutingRequest, RoutingResponse>(channel, new RoutingRequest()
     {
         Operation = RoutingOperation.Lookup,
         Key = key,
         OnlyKBucket = onlyKbucket
     })).Peers);
 }
예제 #11
0
 /// <summary>
 /// Adds a value to the MRU cache and long-term storage
 /// </summary>
 /// <returns>The result of the add operation.</returns>
 /// <param name="channel">The channel to send the request over.</param>
 /// <param name="key">The key of the data to add.</param>
 /// <param name="data">The data to add.</param>
 public static async Task <bool> SendAddAsync(this IWriteChannel <MRURequest> channel, Key key, byte[] data)
 {
     return((await SendMessageAsync <MRURequest, MRUResponse>(channel, new MRURequest()
     {
         Operation = MRUOperation.Add,
         Key = key,
         Data = data
     })).Success);
 }
예제 #12
0
        /// <summary>
        /// Requests a value from the MRU cache or value store
        /// </summary>
        /// <returns>The result or null.</returns>
        /// <param name="channel">The channel to place the request on.</param>
        /// <param name="key">The key to get the data for.</param>
        public static async Task <byte[]> SendGetAsync(this IWriteChannel <MRURequest> channel, Key key)
        {
            var res = await SendMessageAsync <MRURequest, MRUResponse>(channel, new MRURequest()
            {
                Operation = MRUOperation.Get,
                Key       = key
            });

            return(res.Success ? res.Data : null);
        }
예제 #13
0
 /// <summary>
 /// Sends a request and waits for the response
 /// </summary>
 /// <returns>The connection request async.</returns>
 /// <param name="channel">The channel to send the request over</param>
 /// <param name="endPoint">End point.</param>
 /// <param name="key">Key.</param>
 /// <param name="requestId">The request ID</param>
 /// <param name="request">Request.</param>
 public static Task <ConnectionResponse> SendConnectionRequestAsync(this IWriteChannel <ConnectionRequest> channel, EndPoint endPoint, Key key, long requestId, Protocol.Request request)
 {
     return(SendMessageAsync <ConnectionRequest, ConnectionResponse>(channel, new ConnectionRequest()
     {
         EndPoint = endPoint,
         Key = key,
         RequestID = requestId,
         Request = request
     }));
 }
예제 #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CoCoL.ChannelMarkerWrapper&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="attribute">The attribute describing the channel.</param>
        public ChannelMarkerWrapper(ChannelNameAttribute attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException("attribute");
            }
            Attribute = attribute;

            ForWrite = ChannelMarker.ForWrite <T>(attribute);
            ForRead  = ChannelMarker.ForRead <T>(attribute);
        }
예제 #15
0
파일: Prefix.cs 프로젝트: Danstahr/cocol
		public Prefix(IReadChannel<T> input, IWriteChannel<T> output, T value, long repeat = 1)
		{
			if (input == null)
				throw new ArgumentNullException("input");
			if (output == null)
				throw new ArgumentNullException("output");

			m_input = input;
			m_output = output;
			m_value = value;
			m_repeat = repeat;
		}
예제 #16
0
        private static async Task <long> FlushBackend(BackupResults result, IWriteChannel <Backup.IUploadRequest> uploadtarget, Task uploader)
        {
            var flushReq = new Backup.FlushRequest();

            // Wait for upload completion
            result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_WaitForUpload);
            await uploadtarget.WriteAsync(flushReq).ConfigureAwait(false);

            await uploader.ConfigureAwait(false);

            // Grab the size of the last uploaded volume
            return(await flushReq.LastWriteSizeAsync);
        }
예제 #17
0
        /// <summary>
        /// Sets up a simple channel transformation process
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="input">The input channel.</param>
        /// <param name="output">The output channel.</param>
        /// <param name="transform">The method transforming the input</param>
        /// <param name="maxparallel">The maximum number of parallel handlers</param>
        /// <typeparam name="TIn">The input type parameter.</typeparam>
        /// <typeparam name="TOut">The output type parameter.</typeparam>
        public static Task TransformAsync <TIn, TOut>(IReadChannel <TIn> input, IWriteChannel <TOut> output, Func <TIn, Task <TOut> > transform, int maxparallel = 1)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
            if (transform == null)
            {
                throw new ArgumentNullException(nameof(transform));
            }

            return(CollectAsync(input, async data => await output.WriteAsync(await transform(data)), maxparallel));
        }
예제 #18
0
        public Identity(IReadChannel <T> input, IWriteChannel <T> output)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }

            m_input  = input;
            m_output = output;
        }
예제 #19
0
        public static async Task <StreamProcessResult> ProcessStream(IWriteChannel <StreamBlock> channel, string path, Stream stream, bool isMetadata, CompressionHint hint)
        {
            var tcs = new TaskCompletionSource <StreamProcessResult>();
            await channel.WriteAsync(new StreamBlock()
            {
                Path       = path,
                Stream     = stream,
                IsMetadata = isMetadata,
                Hint       = hint,
                Result     = tcs
            });

            return(await tcs.Task);
        }
예제 #20
0
파일: Successor.cs 프로젝트: Danstahr/cocol
        public Successor(IReadChannel <long> input, IWriteChannel <long> output)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }

            m_input  = input;
            m_output = output;
        }
예제 #21
0
        private static async Task UploadVolumeAndIndex(SpillVolumeRequest target, IWriteChannel <IUploadRequest> outputChannel, Options options, BackupDatabase database)
        {
            var blockEntry = target.BlockVolume.CreateFileEntryForUpload(options);

            TemporaryIndexVolume indexVolumeCopy = null;

            if (target.IndexVolume != null)
            {
                indexVolumeCopy = new TemporaryIndexVolume(options);
                target.IndexVolume.CopyTo(indexVolumeCopy, false);
            }

            var uploadRequest = new VolumeUploadRequest(target.BlockVolume, blockEntry, indexVolumeCopy, options, database);
            await outputChannel.WriteAsync(uploadRequest).ConfigureAwait(false);
        }
예제 #22
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();
     }
 }
예제 #23
0
        public ReportSetUploader()
        {
            Channel = m_channel = ChannelManager.CreateChannel<string>(buffersize: MAX_PENDING_UPLOADS);
            FilterChannel = ChannelManager.CreateChannel<string>();

            Terminated = Task.WhenAll(
                RunProtected(async () => {
                    // If we have more than MAX_PENDING_UPLOADS
                    // the newest ones are just discarded
                    // they will be picked up on the later runs

                    while (true)
                        FilterChannel.TryWrite(await m_channel.ReadAsync());
                }),
                RunProtected(Run)
            );
        }
예제 #24
0
        private static async Task UploadVolumeAndIndex(SpillVolumeRequest target, IWriteChannel <IUploadRequest> outputChannel, Options options, BackupDatabase database)
        {
            var blockEntry = CreateFileEntryForUpload(target.BlockVolume, options);

            IndexVolumeWriter indexVolume = null;
            FileEntryItem     indexEntry  = null;

            if (target.IndexVolume != null)
            {
                indexVolume = await target.IndexVolume.CreateVolume(target.BlockVolume.RemoteFilename, blockEntry.Hash, blockEntry.Size, options, database).ConfigureAwait(false);

                indexEntry = CreateFileEntryForUpload(indexVolume, options);
            }

            var uploadRequest = new VolumeUploadRequest(target.BlockVolume, blockEntry, indexVolume, indexEntry);
            await outputChannel.WriteAsync(uploadRequest).ConfigureAwait(false);
        }
예제 #25
0
        /// <summary>
        /// A process that produces an infinite amount of numbers,
        /// given an offset and an increment
        /// </summary>
        /// <returns>The awaitable task that represents the process</returns>
        /// <param name="from">The number offset.</param>
        /// <param name="increment">The increment.</param>
        /// <param name="target">The channel to which the numbers are written.</param>
        private static async Task RunNumbersFromAsync(long from, long increment, IWriteChannel <long> target)
        {
            var n = from;

            try
            {
                while (true)
                {
                    await target.WriteAsync(n);

                    n += increment;
                }
            }
            catch (RetiredException)
            {
            }
        }
예제 #26
0
        /// <summary>
        /// Write to the channel in a blocking manner
        /// </summary>
        /// <param name="value">The value to write into the channel</param>
        /// <param name="self">The channel to read from</param>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        public static void Write <T>(this IWriteChannel <T> self, T value)
        {
            var res = self.WriteAsync(value, Timeout.Infinite).WaitForTask();

            if (res.Exception != null)
            {
                if (res.Exception is AggregateException && ((AggregateException)res.Exception).Flatten().InnerExceptions.Count == 1)
                {
                    throw ((AggregateException)res.Exception).InnerException;
                }

                throw res.Exception;
            }
            else if (res.IsCanceled)
            {
                throw new OperationCanceledException();
            }
        }
예제 #27
0
        /// <summary>
        /// Constructs a new runner
        /// </summary>
        /// <param name="options">The options to use</param>
        /// <param name="reqchan">The request channel</param>
        /// <param name="respchan">The response channel</param>
        /// <param name="response">The expected response string</param>
        public WebRequestWorker(IWorkerOptions options, IReadChannel <bool> reqchan, IWriteChannel <RequestResult> respchan, string response)
        //: base(options, maximumrequests, response)
            : base(options, reqchan, respchan, response)
        {
            foreach (var h in options.Headers)
            {
                var parts = h?.Split(':', 2);
                if (parts == null || parts.Length < 2)
                {
                    throw new ArgumentException($"Bad header format: {h}");
                }

                m_headers.Add(parts[0], parts[1]);
            }

            m_data = string.IsNullOrEmpty(options.Body) ? null : System.Text.Encoding.UTF8.GetBytes(options.Body);
            m_initialized.TrySetResult(true);
        }
예제 #28
0
        /// <summary>
        /// Write to the channel in a blocking manner
        /// </summary>
        /// <param name="value">The value to write into the channel</param>
        /// <param name="self">The channel to read from</param>
        /// <param name="timeout">The maximum time to wait for an available slot</param>
        /// <typeparam name="T">The channel data type parameter.</typeparam>
        public static void Write <T>(this IWriteChannel <T> self, T value, TimeSpan timeout)
        {
            var res = self.WriteAsync(value, new TimeoutOffer(timeout)).WaitForTask();

            if (res.Exception != null)
            {
                if (res.Exception.Flatten().InnerExceptions.Count == 1)
                {
                    throw res.Exception.InnerException;
                }

                throw res.Exception;
            }
            else if (res.IsCanceled)
            {
                throw new OperationCanceledException();
            }
        }
예제 #29
0
파일: Delta.cs 프로젝트: Danstahr/cocol
        public Delta(IReadChannel <T> input, IWriteChannel <T> outputA, IWriteChannel <T> outputB)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (outputA == null)
            {
                throw new ArgumentNullException("outputA");
            }
            if (outputB == null)
            {
                throw new ArgumentNullException("outputB");
            }

            m_input   = input;
            m_outputA = outputA;
            m_outputB = outputB;
        }
예제 #30
0
        // The Primes process

        /// <summary>
        /// A process that outputs the number 2, then
        /// spawns the sieve and a number generating process
        /// that produces numbers from 3 and forward
        /// </summary>
        /// <returns>The awaitable task that represents the process</returns>
        /// <param name="target">The channel the numbers are written into.</param>
        private static async Task RunPrimesAsync(IWriteChannel <long> target)
        {
            var chan = ChannelManager.CreateChannel <long>();

            try
            {
                await target.WriteAsync(2);

                await Task.WhenAll(
                    RunNumbersFromAsync(3, 2, chan),
                    RunSieveAsync(chan, target)
                    );
            }
            catch (RetiredException)
            {
                chan.Retire();
                target.Retire();
            }
        }
예제 #31
0
        public ReportSetUploader()
        {
            Channel       = m_channel = ChannelManager.CreateChannel <string>(buffersize: MAX_PENDING_UPLOADS);
            FilterChannel = ChannelManager.CreateChannel <string>();

            Terminated = Task.WhenAll(
                RunProtected(async() => {
                // If we have more than MAX_PENDING_UPLOADS
                // the newest ones are just discarded
                // they will be picked up on the later runs

                while (true)
                {
                    FilterChannel.TryWrite(await m_channel.ReadAsync());
                }
            }),
                RunProtected(Run)
                );
        }
예제 #32
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Duplicati.Library.UsageReporter.EventProcessor"/> class.
        /// </summary>
        /// <param name="forwardChannel">The forwarding destination.</param>
        public EventProcessor(IWriteChannel<string> forwardChannel)
        {
            INSTANCE_ID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();

            Channel = m_channel = ChannelManager.CreateChannel<ReportItem>(null, MAX_QUEUE_SIZE);
            m_forward = forwardChannel;
            Terminated = RunProtected(Run);
        }
예제 #33
0
        /// <summary>
        /// Initializes the usage reporter library
        /// </summary>
        public static void Initialize()
        {
            if (_eventChannel == null || _eventChannel.IsRetired)
            {
                if (IsDisabled)
                    return;

                var rsu = new ReportSetUploader();
                var ep = new EventProcessor(rsu.Channel);
                _eventChannel = ep.Channel;

                ShutdownTask = Task.WhenAll(ep.Terminated, rsu.Terminated);

                // TODO: Disable on debug builds
                AppDomain.CurrentDomain.UnhandledException += HandleUncaughtException;
                //AppDomain.CurrentDomain.UnhandledException += HandleUncaughtException;
                //AppDomain.CurrentDomain.ProcessExit

                Report("Started");
            }
        }