Ejemplo n.º 1
0
        protected Task ShutdownAsync(QbservableProtocolShutdownReason reason)
        {
            Contract.Ensures(Contract.Result <Task>() != null);

            ShutdownReason |= reason;

            return(ShutdownCoreAsync());
        }
Ejemplo n.º 2
0
 private TcpClientTermination(SerializationInfo info, StreamingContext context)
 {
     localEndPoint  = (EndPoint)info.GetValue("localEndPoint", typeof(EndPoint));
     remoteEndPoint = (EndPoint)info.GetValue("remoteEndPoint", typeof(EndPoint));
     duration       = (TimeSpan)info.GetValue("duration", typeof(TimeSpan));
     reason         = (QbservableProtocolShutdownReason)info.GetValue("reason", typeof(QbservableProtocolShutdownReason));
     exceptions     = ((List <Exception>)info.GetValue("rawExceptions", typeof(List <Exception>)))
                      .Select(ExceptionDispatchInfo.Capture)
                      .ToList()
                      .AsReadOnly();
 }
Ejemplo n.º 3
0
        public void CancelAllCommunication(ExceptionDispatchInfo exception)
        {
            exceptions.Add(exception);

            if (!protocolCancellation.IsCancellationRequested)
            {
                ShutdownReason |= QbservableProtocolShutdownReason.ServerError;

                CancelAllCommunication();
            }
        }
Ejemplo n.º 4
0
        public WebSocketClientTermination(
            Uri uri,
            string origin,
            TimeSpan duration,
            QbservableProtocolShutdownReason reason,
            IEnumerable <ExceptionDispatchInfo> exceptions)
            : base(duration, reason, exceptions)
        {
            Contract.Requires(uri != null);
            Contract.Requires(duration >= TimeSpan.Zero);

            Uri    = uri;
            Origin = origin;
        }
Ejemplo n.º 5
0
        public ClientTermination(
            TimeSpan duration,
            QbservableProtocolShutdownReason reason,
            IEnumerable <ExceptionDispatchInfo> exceptions)
        {
            Contract.Requires(duration >= TimeSpan.Zero);

            Duration   = duration;
            Reason     = reason;
            Exceptions = (exceptions ?? Enumerable.Empty <ExceptionDispatchInfo>())
                         .Distinct(ExceptionDispatchInfoEqualityComparer.Instance)
                         .ToList()
                         .AsReadOnly();
        }
Ejemplo n.º 6
0
        public TcpClientTermination(
            EndPoint localEndPoint,
            EndPoint remoteEndPoint,
            TimeSpan duration,
            QbservableProtocolShutdownReason reason,
            IEnumerable <ExceptionDispatchInfo> exceptions)
            : base(duration, reason, exceptions)
        {
            Contract.Requires(localEndPoint != null);
            Contract.Requires(remoteEndPoint != null);
            Contract.Requires(duration >= TimeSpan.Zero);

            LocalEndPoint  = localEndPoint;
            RemoteEndPoint = remoteEndPoint;
        }
Ejemplo n.º 7
0
 public TcpClientTermination(
     EndPoint localEndPoint,
     EndPoint remoteEndPoint,
     TimeSpan duration,
     QbservableProtocolShutdownReason reason,
     IEnumerable <ExceptionDispatchInfo> exceptions)
 {
     this.localEndPoint  = localEndPoint;
     this.remoteEndPoint = remoteEndPoint;
     this.duration       = duration;
     this.reason         = reason;
     this.exceptions     = (exceptions ?? Enumerable.Empty <ExceptionDispatchInfo>())
                           .Distinct(ExceptionDispatchInfoEqualityComparer.Instance)
                           .ToList()
                           .AsReadOnly();
 }
Ejemplo n.º 8
0
        private async void Shutdown(WebSocket socket, QbservableProtocolShutdownReason reason, object id = null)
        {
            Contract.Requires(socket != null);

            try
            {
                if (IsConnectedSafe(socket))
                {
                    if (IsServer)
                    {
                        Disconnecting(idOverride: id);

                        await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, reason.ToString(), CancellationToken.None).ConfigureAwait(false);
                    }
                    else
                    {
                        Stopping();

                        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, reason.ToString(), CancellationToken.None).ConfigureAwait(false);
                    }
                }
            }
            catch (ObjectDisposedException)
            {
            }
            catch (WebSocketException ex)
            {
                QactiveTraceSources.Qactive.TraceEvent(TraceEventType.Warning, 0, Id + " - " + ex);
            }
            finally
            {
                socket.Dispose();

                if (IsServer)
                {
                    Disconnected(idOverride: id);
                }
                else
                {
                    Stopped();
                }
            }
        }
Ejemplo n.º 9
0
        protected async Task ShutdownAsync(QbservableProtocolShutdownReason reason)
        {
            ShutdownReason = reason;

            await ShutdownCoreAsync().ConfigureAwait(false);
        }
Ejemplo n.º 10
0
 protected override QbservableProtocolShutdownReason GetShutdownReason(TestMessage message, QbservableProtocolShutdownReason defaultReason)
 => defaultReason;
Ejemplo n.º 11
0
 private static QbservableProtocolShutdownReason GetShutdownReason(QbservableMessage message, QbservableProtocolShutdownReason defaultReason)
 {
     if (message.Data.Length > 0)
     {
         return((QbservableProtocolShutdownReason)message.Data[0]);
     }
     else
     {
         return(defaultReason);
     }
 }
Ejemplo n.º 12
0
        protected void ShutdownWithoutResponse(QbservableProtocolShutdownReason reason)
        {
            ShutdownReason |= reason;

            CancelAllCommunication();
        }
 protected abstract QbservableProtocolShutdownReason GetShutdownReason(TMessage message, QbservableProtocolShutdownReason defaultReason);
Ejemplo n.º 14
0
        private async Task SendObservableAsync(object untypedObservable, Type dataType, bool sendServerErrorsToClients, CancellationToken cancel)
        {
            Contract.Requires(untypedObservable != null);
            Contract.Requires(dataType != null);

            var networkErrors = new ConcurrentBag <ExceptionDispatchInfo>();

            ExceptionDispatchInfo expressionSecurityError     = null;
            ExceptionDispatchInfo qbservableSubscriptionError = null;
            ExceptionDispatchInfo qbservableError             = null;

            var terminationKind = NotificationKind.OnCompleted;

            try
            {
                var cancelSubscription = new CancellationTokenSource();

                cancel.Register(cancelSubscription.Cancel);

                IObservable <object> observable;

#if CAS
                new PermissionSet(PermissionState.Unrestricted).Assert();
#endif

                try
                {
                    observable = dataType.UpCast(untypedObservable);
                }
                finally
                {
#if CAS
                    PermissionSet.RevertAssert();
#endif
                }

                await observable
                .TraceSubscriptions(ServiceObservableName, true, true, ClientId)
                .TraceNotifications(ServiceObservableName, true, true, ClientId)
                .ForEachAsync(
                    async data =>
                {
                    try
                    {
                        await ServerSendAsync(NotificationKind.OnNext, data).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    catch (Exception ex)
                    {
                        /* Collecting exceptions handles a possible race condition.  Since this code is using a fire-and-forget model to
                         * subscribe to the observable, due to the async OnNext handler, it's possible that more than one SendAsync task
                         * can be executing concurrently.  As a result, canceling the cancelSubscription below does not guarantee that
                         * this catch block won't run again.
                         */
                        networkErrors.Add(ExceptionDispatchInfo.Capture(ex));

                        cancelSubscription.Cancel();
                    }
                },
                    cancelSubscription.Token)
                .ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                if (cancel.IsCancellationRequested && networkErrors.Count == 0)
                {
                    throw;
                }
            }
            catch (ExpressionSecurityException ex)
            {
                ShutdownReason = QbservableProtocolShutdownReason.ExpressionSecurityViolation;

                expressionSecurityError = ExceptionDispatchInfo.Capture(ex);
            }
            catch (QbservableSubscriptionException ex)
            {
                ShutdownReason = QbservableProtocolShutdownReason.ExpressionSubscriptionException;

                qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex.InnerException ?? ex);
            }
            catch (TargetInvocationException ex)
            {
                if (ex.InnerException is QbservableSubscriptionException)
                {
                    ShutdownReason = QbservableProtocolShutdownReason.ExpressionSubscriptionException;

                    qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex.InnerException.InnerException ?? ex.InnerException);
                }
                else
                {
                    qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex);
                }
            }
            catch (Exception ex)
            {
                terminationKind = NotificationKind.OnError;
                qbservableError = ExceptionDispatchInfo.Capture(ex);
            }

            var error = expressionSecurityError ?? qbservableSubscriptionError;

            if (error != null)
            {
                if (networkErrors.Count > 0)
                {
                    // It's not technically a network error, but since the client can't receive it anyway add it so that it's thrown later
                    networkErrors.Add(error);
                }
                else
                {
                    if (sendServerErrorsToClients || expressionSecurityError != null)
                    {
                        var exception = expressionSecurityError == null
              ? error.SourceException
              : new SecurityException(error.SourceException.Message);   // Remove stack trace

                        await ServerSendAsync(NotificationKind.OnError, exception).ConfigureAwait(false);
                    }

                    error.Throw();
                }
            }

            /* There's an acceptable race condition here whereby ForEachAsync is canceled by the external cancellation token though
             * it's still executing a fire-and-forget task.  It's possible for the fire-and-forget task to throw before seeing the
             * cancellation, yet after the following code has already executed.  In that case, since the cancellation was requested
             * externally, it's acceptable for the cancellation to simply beat the send error, thus the error can safely be ignored.
             */
            if (networkErrors.Count > 0)
            {
                throw new AggregateException(networkErrors.Select(e => e.SourceException));
            }
            else
            {
                try
                {
                    await ServerSendAsync(terminationKind, (qbservableError == null ? null : qbservableError.SourceException)).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                }

                if (qbservableError != null)
                {
                    qbservableError.Throw();
                }
            }
        }
Ejemplo n.º 15
0
        public async Task ExecuteServerAsync(IQbservableProvider provider)
        {
            Task receivingAsync = null;
            ExceptionDispatchInfo fatalException = null;

            try
            {
                await InitializeSinksAsync().ConfigureAwait(false);

                var input = await ServerReceiveQueryAsync().ConfigureAwait(false);

                receivingAsync = ServerReceiveAsync();

                try
                {
                    await ExecuteServerQueryAsync(input, provider).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    ShutdownReason |= QbservableProtocolShutdownReason.BadClientRequest;

                    fatalException = ExceptionDispatchInfo.Capture(ex);

                    CancelAllCommunication(fatalException);
                }
            }
            catch (OperationCanceledException ex)
            {
                var exception = TryRollupExceptions();

                if (exception != null)
                {
                    ShutdownReason |= QbservableProtocolShutdownReason.ServerError;

                    fatalException = exception;
                }

                ShutdownReason |= QbservableProtocolShutdownReason.ClientTerminated;

                fatalException = ExceptionDispatchInfo.Capture(ex);
            }
            catch (Exception ex)
            {
                fatalException = ExceptionDispatchInfo.Capture(ex);

                CancelAllCommunication(fatalException);
            }

            if (receivingAsync != null)
            {
                try
                {
                    await receivingAsync.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    AddError(ExceptionDispatchInfo.Capture(ex));
                }
            }

            if (fatalException != null)
            {
                fatalException.Throw();
            }
        }
 protected override QbservableProtocolShutdownReason GetShutdownReason(TMessage message, QbservableProtocolShutdownReason defaultReason)
 {
     Contract.Requires(message != null);
     return(default(QbservableProtocolShutdownReason));
 }
Ejemplo n.º 17
0
  protected override QbservableProtocolShutdownReason GetShutdownReason(StreamMessage message, QbservableProtocolShutdownReason defaultReason)
  => message.Data.Length > 0
 ? (QbservableProtocolShutdownReason)message.Data[0]
 : defaultReason;