Ejemplo n.º 1
0
        private void ProcessRequest(IRingMasterRequest request, Action<RequestResponse, Exception> onCompletion)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            switch (request.RequestType)
            {
                case RingMasterRequestType.Init:
                    {
                        var initRequest = (RequestInit)request;

                        this.requestHandler = this.onInitSession(initRequest);

                        var initResponse = new RequestResponse
                        {
                            ResultCode = (int)RingMasterException.Code.Ok,
                            Content = new string[] { initRequest.SessionId.ToString(), Guid.NewGuid().ToString() },
                        };

                        this.requestOrdering.Release();

                        RingMasterServerEventSource.Log.ProcessSessionInit(this.Id, initResponse.ResultCode);
                        onCompletion?.Invoke(initResponse, null);
                        return;
                    }

                case RingMasterRequestType.GetData:
                    {
                        var getDataRequest = (RequestGetData)request;
                        getDataRequest.Watcher = this.MakeWatcher(getDataRequest.Watcher);
                        break;
                    }

                case RingMasterRequestType.GetChildren:
                    {
                        var getChildrenRequest = (RequestGetChildren)request;
                        getChildrenRequest.Watcher = this.MakeWatcher(getChildrenRequest.Watcher);
                        break;
                    }

                case RingMasterRequestType.Exists:
                    {
                        var existsRequest = (RequestExists)request;
                        existsRequest.Watcher = this.MakeWatcher(existsRequest.Watcher);
                        break;
                    }
            }

            if (this.server.Redirect != null)
            {
                RedirectSuggested redirect = this.server.Redirect();

                this.requestOrdering.Release();

                RingMasterServerEventSource.Log.RedirectionSuggested(this.Id, redirect?.SuggestedConnectionString);
                onCompletion?.Invoke(
                    new RequestResponse()
                    {
                        ResponsePath = request.Path,
                        ResultCode = (int)RingMasterException.Code.Sessionmoved,
                        Stat = default(Stat),
                        Content = redirect,
                    },
                    null);

                return;
            }

            if (this.requestHandler != null)
            {
                QueuedWorkItemPool.Default.Queue(
                    () =>
                    {
                        // Give a signal that the next request can be started. For read requests in the same session,
                        // they may be processed concurrently. For write requests, they will be ordered by locking.
                        this.requestOrdering.Release();

                        this.requestHandler.RequestOverlapped(request, onCompletion);
                    });
                return;
            }

            throw new InvalidOperationException("Session has not been initialized");
        }
Ejemplo n.º 2
0
        private RequestResponse ProcessRequest(IRingMasterRequest request, IZooKeeperRequest zkprRequest)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (zkprRequest == null)
            {
                throw new ArgumentNullException(nameof(zkprRequest));
            }

            switch (request.RequestType)
            {
            case RingMasterRequestType.Init:
            {
                var             initRequest  = (Requests.RequestInit)request;
                RequestResponse initResponse = null;

                if (this.requestHandler == null)
                {
                    this.requestHandler = this.onInitSession(initRequest);
                    if (((zkprRequest as ZkprProtocolMessages.CreateSession).SessionId != 0) || (zkprRequest as ZkprProtocolMessages.CreateSession).IsNullPassword == false)
                    {
                        initResponse = new RequestResponse
                        {
                            ResultCode = (int)RingMasterException.Code.Authfailed,
                            Content    = new string[] { "0", string.Empty },
                        };
                    }
                }

                if (initResponse == null)
                {
                    initResponse = (this.requestHandler as CoreRequestHandler).InitResponse;
                }

                ZooKeeperServerEventSource.Log.ProcessSessionInit(this.Id, initResponse.ResultCode);
                return(initResponse);
            }

            case RingMasterRequestType.GetData:
            {
                var getDataRequest = (Requests.RequestGetData)request;
                getDataRequest.Watcher = this.MakeWatcher(getDataRequest.Watcher);
                break;
            }

            case RingMasterRequestType.GetChildren:
            {
                var getChildrenRequest = (Requests.RequestGetChildren)request;
                getChildrenRequest.Watcher = this.MakeWatcher(getChildrenRequest.Watcher);
                break;
            }

            case RingMasterRequestType.Exists:
            {
                var existsRequest = (Requests.RequestExists)request;
                existsRequest.Watcher = this.MakeWatcher(existsRequest.Watcher);
                break;
            }
            }

            if (this.server.Redirect != null)
            {
                RedirectSuggested redirect = this.server.Redirect();

                ZooKeeperServerEventSource.Log.RedirectionSuggested(this.Id, redirect?.SuggestedConnectionString);
                return(new RequestResponse()
                {
                    ResponsePath = request.Path,
                    ResultCode = (int)RingMasterException.Code.Sessionmoved,
                    Stat = default(Stat),
                    Content = redirect,
                });
            }

            if (this.requestHandler != null)
            {
                using (var completed = new AutoResetEvent(false))
                {
                    RequestResponse response = null;
                    this.requestHandler.RequestOverlapped(request, (r, e) =>
                    {
                        response = r;
                        completed.Set();
                    });

                    completed.WaitOne();
                    return(response);
                }
            }

            throw new InvalidOperationException("Session has not been initialized");
        }