Beispiel #1
0
        public IFuture <StreamItemContainer <TResult> > Stream <TResult>(string target, params object[] args)
        {
            var future = new Future <StreamItemContainer <TResult> >();

            long id = InvokeImp(target,
                                args,
                                callback: (message) =>
            {
                switch (message.type)
                {
                // StreamItem message contains only one item.
                case Messages.MessageTypes.StreamItem:
                    {
                        var container = future.value;

                        if (container.IsCanceled)
                        {
                            break;
                        }

                        container.AddItem((TResult)this.Protocol.ConvertTo(typeof(TResult), message.item));

                        // (re)assign the container to raise OnItem event
                        future.AssignItem(container);
                        break;
                    }

                case Messages.MessageTypes.Completion:
                    {
                        bool isSuccess = string.IsNullOrEmpty(message.error);
                        if (isSuccess)
                        {
                            var container = future.value;

                            // While completion message must not contain any result, this should be future-proof
                            //if (!container.IsCanceled && message.Result != null)
                            //{
                            //    TResult[] results = (TResult[])this.Protocol.ConvertTo(typeof(TResult[]), message.Result);
                            //
                            //    container.AddItems(results);
                            //}

                            future.Assign(container);
                        }
                        else
                        {
                            future.Fail(new Exception(message.error));
                        }
                        break;
                    }
                }
            },
                                isStreamingInvocation: true);

            future.BeginProcess(new StreamItemContainer <TResult>(id));

            return(future);
        }
        public UpStreamItemController <TResult> GetUpStreamController <TResult>(string target, int paramCount, bool downStream = false)
        {
            Future <TResult> future = new Future <TResult>();

            future.BeginProcess();

            long invocationId = System.Threading.Interlocked.Increment(ref this.lastInvocationId);

            string[] streamIds = new string[paramCount];
            for (int i = 0; i < paramCount; i++)
            {
                streamIds[i] = System.Threading.Interlocked.Increment(ref this.lastStreamId).ToString();
            }

            var controller = new UpStreamItemController <TResult>(this, invocationId, streamIds, future);

            Action <Message> callback = (Message msg) => {
                switch (msg.type)
                {
                // StreamItem message contains only one item.
                case MessageTypes.StreamItem:
                {
                    if (controller.IsCanceled)
                    {
                        break;
                    }

                    TResult item = (TResult)this.Protocol.ConvertTo(typeof(TResult), msg.item);

                    future.AssignItem(item);
                    break;
                }

                case MessageTypes.Completion:
                {
                    bool isSuccess = string.IsNullOrEmpty(msg.error);
                    if (isSuccess)
                    {
                        // While completion message must not contain any result, this should be future-proof
                        if (!controller.IsCanceled && msg.result != null)
                        {
                            TResult result = (TResult)this.Protocol.ConvertTo(typeof(TResult), msg.result);

                            future.AssignItem(result);
                        }

                        future.Finish();
                    }
                    else
                    {
                        var ex = new Exception(msg.error);
                        future.Fail(ex);
                    }
                    break;
                }
                }
            };

            var messageToSend = new Message
            {
                type         = downStream ? MessageTypes.StreamInvocation : MessageTypes.Invocation,
                invocationId = invocationId.ToString(),
                target       = target,
                arguments    = new object[0],
                streamIds    = streamIds,
                nonblocking  = false,
            };

            SendMessage(messageToSend);

            this.invocations.Add(invocationId, new InvocationDefinition {
                callback = callback, returnType = typeof(TResult)
            });

            return(controller);
        }
        public DownStreamItemController <TDown> GetDownStreamController <TDown>(string target, params object[] args)
        {
            long invocationId = System.Threading.Interlocked.Increment(ref this.lastInvocationId);

            var future = new Future <TDown>();

            future.BeginProcess();

            var controller = new DownStreamItemController <TDown>(this, invocationId, future);

            Action <Message> callback = (Message msg) =>
            {
                switch (msg.type)
                {
                // StreamItem message contains only one item.
                case MessageTypes.StreamItem:
                {
                    if (controller.IsCanceled)
                    {
                        break;
                    }

                    TDown item = (TDown)this.Protocol.ConvertTo(typeof(TDown), msg.item);

                    future.AssignItem(item);
                    break;
                }

                case MessageTypes.Completion:
                {
                    bool isSuccess = string.IsNullOrEmpty(msg.error);
                    if (isSuccess)
                    {
                        // While completion message must not contain any result, this should be future-proof
                        if (!controller.IsCanceled && msg.result != null)
                        {
                            TDown result = (TDown)this.Protocol.ConvertTo(typeof(TDown), msg.result);

                            future.AssignItem(result);
                        }

                        future.Finish();
                    }
                    else
                    {
                        future.Fail(new Exception(msg.error));
                    }
                    break;
                }
                }
            };

            var message = new Message
            {
                type         = MessageTypes.StreamInvocation,
                invocationId = invocationId.ToString(),
                target       = target,
                arguments    = args,
                nonblocking  = false,
            };

            SendMessage(message);

            if (callback != null)
            {
                this.invocations.Add(invocationId, new InvocationDefinition {
                    callback = callback, returnType = typeof(TDown)
                });
            }

            return(controller);
        }
        internal UploadItemController <StreamItemContainer <TResult> > UploadStreamWithDownStream <TResult>(string target, int paramCount)
        {
            Future <StreamItemContainer <TResult> > future = new Future <StreamItemContainer <TResult> >();

            Action <Message> callback = (Message message) => {
                switch (message.type)
                {
                // StreamItem message contains only one item.
                case MessageTypes.StreamItem:
                {
                    StreamItemContainer <TResult> container = future.value;

                    if (container.IsCanceled)
                    {
                        break;
                    }

                    container.AddItem((TResult)this.Protocol.ConvertTo(typeof(TResult), message.item));

                    // (re)assign the container to raise OnItem event
                    future.AssignItem(container);
                    break;
                }

                case MessageTypes.Completion:
                {
                    bool isSuccess = string.IsNullOrEmpty(message.error);
                    if (isSuccess)
                    {
                        StreamItemContainer <TResult> container = future.value;

                        // While completion message must not contain any result, this should be future-proof
                        if (!container.IsCanceled && message.result != null)
                        {
                            TResult result = (TResult)this.Protocol.ConvertTo(typeof(TResult), message.result);

                            container.AddItem(result);
                        }

                        future.Assign(container);
                    }
                    else
                    {
                        future.Fail(new Exception(message.error));
                    }
                    break;
                }
                }
            };

            long invocationId = System.Threading.Interlocked.Increment(ref this.lastInvocationId);

            int[] streamIds = new int[paramCount];
            for (int i = 0; i < paramCount; i++)
            {
                streamIds[i] = System.Threading.Interlocked.Increment(ref this.lastStreamId);
            }

            var controller = new UploadItemController <StreamItemContainer <TResult> >(this, invocationId, streamIds, future);

            var messageToSend = new Message
            {
                type         = MessageTypes.StreamInvocation,
                invocationId = invocationId.ToString(),
                target       = target,
                arguments    = new object[0],
                streamIds    = streamIds,
                nonblocking  = false,
            };

            SendMessage(messageToSend);

            this.invocations.Add(invocationId, callback);

            future.BeginProcess(new StreamItemContainer <TResult>(invocationId));
            return(controller);
        }