/// <summary> /// Enqueue a request. /// </summary> /// <param name="request">Request to enqueue</param> /// <returns>A task that resolves to the response sent by the server</returns> public async Task <RequestResponse> Request(IRingMasterRequest request) { // Register the request in the requestMap - the request map keeps track of the request // throughout its lifetime. RequestWrapper requestWrapper = this.RegisterRequest(request); // Attempt to add the request to the outgoing request queue. if (this.outgoingRequests.TryAdd(requestWrapper)) { // Once the request is added to the outgoing request queue, it stays there until a connection // is available to send it. If the request's timeout expires before a connection is available, then // the request is completed with OperationTimedout resultCode. this.instrumentation.RequestQueued(requestWrapper.CallId, requestWrapper.WrappedRequest.RequestType, this.outgoingRequests.Count); this.outgoingRequestsAvailable.Release(); } else { // The outgoing request queue is full, so remove the request from the requestMap and throw a RequestQueueFull exception. lock (this.requestMap) { this.RemoveRequestFromMap(requestWrapper.CallId); } int pendingRequestCount = this.outgoingRequestsAvailable.CurrentCount; RingMasterClientEventSource.Log.RequestQueueFull(requestWrapper.CallId, pendingRequestCount); this.instrumentation.RequestQueueFull(requestWrapper.CallId, requestWrapper.WrappedRequest.RequestType, pendingRequestCount); throw RingMasterClientException.RequestQueueFull(pendingRequestCount); } return(await requestWrapper.TaskCompletionSource.Task); }
/// <summary> /// Enqueue a request. /// </summary> /// <param name="request">Request to enqueue</param> /// <returns>A task that resolves to the response sent by the server</returns> public async Task <RequestResponse> Request(IRingMasterRequest request) { bool haswatcher = false; switch (request.RequestType) { case RingMasterRequestType.Exists: { var existsRequest = (RequestExists)request; haswatcher = existsRequest.Watcher != null; break; } case RingMasterRequestType.GetData: { var getDataRequest = (RequestGetData)request; haswatcher = getDataRequest.Watcher != null; break; } case RingMasterRequestType.GetChildren: { var getChildrenRequest = (RequestGetChildren)request; haswatcher = getChildrenRequest.Watcher != null; break; } } if (!haswatcher) { return(await this.ProcessCacheRequest(this.cache, request)); } return(await this.baseHandler.Request(request)); }
/// <summary> /// Initializes a new instance of the <see cref="RequestWrapper"/> class. /// </summary> /// <param name="callId">Id of the call</param> /// <param name="wrappedRequest">Request to wrap</param> public RequestWrapper(ulong callId, IRingMasterRequest wrappedRequest) { this.WrappedRequest = wrappedRequest; this.TaskCompletionSource = new TaskCompletionSource <RequestResponse>(); this.CallId = callId; this.creationTimeTicks = DateTime.UtcNow.Ticks; }
/// <summary> /// Process a request /// </summary> /// <param name="request">Request to be processed</param> /// <returns> /// Task that resolves to the response corresponding to the request /// </returns> public Task <RequestResponse> Request(IRingMasterRequest request) { return(this.Request <RequestResponse>(ringMaster => { return ringMaster.Request(request); })); }
/// <inheritdoc/> public Task <RequestResponse> Request(IRingMasterRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } request.TimeStreamId = this.timeStreamId; return(this.handler.Request(request)); }
/// <summary> /// Registers the request. /// </summary> /// <param name="request">Request to register</param> /// <returns>Wrapper that represents the request and its metadata</returns> private RequestWrapper RegisterRequest(IRingMasterRequest request) { RequestWrapper requestWrapper; lock (this.requestMap) { requestWrapper = this.AddRequestToMap(request); } return(requestWrapper); }
/// <summary> /// Gets <see cref="IRingMasterRequest"/> that correspond to the given <see cref="Op"/>s. /// </summary> /// <param name="ops">List of operations</param> /// <returns>List of <see cref="IRingMasterRequest"/>s</returns> protected static IReadOnlyList <IRingMasterRequest> GetRequests(IReadOnlyList <Op> ops) { if (ops == null) { throw new ArgumentNullException("ops"); } IRingMasterRequest[] requests = new IRingMasterRequest[ops.Count]; for (int i = 0; i < requests.Length; i++) { requests[i] = ops[i].Request; } return(requests); }
/// <summary> /// Deserialize <see cref="RequestBatch"/>. /// </summary> /// <param name="callid">Id of the call</param> /// <param name="uid"><c>uid</c> associated with the request</param> /// <returns>The deserialized request</returns> private RequestBatch DeserializeRequestBatch(ulong callid, ulong uid) { ushort numReq = this.binaryReader.ReadUInt16(); IRingMasterRequest[] req = new IRingMasterRequest[numReq]; for (int i = 0; i < req.Length; i++) { this.DeserializeRingMasterRequest(callid, out req[i]); } bool completeSynchronously = this.binaryReader.ReadBoolean(); return(new RequestBatch(req, completeSynchronously, uid)); }
/// <summary> /// Create a batch request which contains the given requests and book keeping requests. /// </summary> /// <param name="batchId">Id of the batch</param> /// <param name="requests">Requests to include in the batch</param> /// <returns>A <see cref="RequestBatch"/> that contains the given requests and book keeping requests</returns> private static RequestBatch CreateBatch(ulong batchId, params IRingMasterRequest[] requests) { var requestArray = new IRingMasterRequest[2 + requests.Length]; requestArray[0] = new RequestSetData(TestExecutionQueue.LastAppliedBatchIdPath, data: BitConverter.GetBytes(batchId), version: -1); requests.CopyTo(requestArray, 1); requestArray[requestArray.Length - 1] = new RequestGetData(TestExecutionQueue.TransactionCrcPath, options: RequestGetData.GetDataOptions.None, watcher: null); var batchRequest = new RequestBatch(requestArray, completeSynchronously: true); batchRequest.Uid = batchId; batchRequest.ExecutionQueueId = TransactionManagerExecutionQueueId; batchRequest.ExecutionQueueTimeoutMillis = 10000; return(batchRequest); }
/// <inheritdoc /> public Task <RequestResponse> Request(IRingMasterRequest request) { var tcs = new TaskCompletionSource <RequestResponse>(); this.RequestOverlapped( request, (response, ex) => { if (ex != null) { tcs.SetException(ex); } else { tcs.SetResult(response); } }); return(tcs.Task); }
/// <summary> /// Handles ringmaster requests. /// </summary> /// <param name="request">RingMaster request</param> /// <param name="onCompletion">Action to execute when the replication is completed</param> /// <remarks> /// Implementing the <see cref="IRingMasterRequestHandlerOverlapped"/> makes it possible for /// several libraries to work directly with the RingMasterBackendCore. This class /// is being implemented here to avoid having to expose internal classes outside of /// this library. /// </remarks> public void RequestOverlapped(IRingMasterRequest request, Action <RequestResponse, Exception> onCompletion) { if (request == null) { throw new ArgumentNullException(nameof(request)); } RequestCall call = MarshallerChannel.LocalRequest(request); call.CallId = (ulong)Interlocked.Increment(ref this.lastAssignedCallId); this.executor.ProcessMessage( call.Request, this.session, (response, ex) => { response.CallId = call.CallId; onCompletion?.Invoke(response, ex); }); }
private RequestResponse Process(IRingMasterRequest req, List <Action> actions) { IRingMasterBackendRequest breq = req as IRingMasterBackendRequest; if (breq != null) { req = breq.WrappedRequest; } switch (req.RequestType) { case RingMasterRequestType.Check: return(this.ProcessT((Requests.RequestCheck)req, actions)); case RingMasterRequestType.Create: return(this.ProcessT((Requests.RequestCreate)req, actions)); case RingMasterRequestType.GetChildren: return(this.ProcessT((Requests.RequestGetChildren)req, actions)); case RingMasterRequestType.GetData: return(this.ProcessT((Requests.RequestGetData)req, actions)); case RingMasterRequestType.Delete: return(this.ProcessT((Requests.RequestDelete)req, actions)); case RingMasterRequestType.Exists: return(this.ProcessT((Requests.RequestExists)req, actions)); case RingMasterRequestType.Multi: return(this.ProcessT((Requests.RequestMulti)req, actions)); case RingMasterRequestType.Move: return(this.ProcessT((Requests.RequestMove)req, actions)); } return(new RequestResponse() { ResultCode = (int)RingMasterException.Code.Unimplemented }); }
private string ToString(IRingMasterRequest req) { IRingMasterBackendRequest breq = req as IRingMasterBackendRequest; if (breq != null) { req = breq.WrappedRequest; } if (req.RequestType == RingMasterRequestType.Multi) { return(string.Format("Request[Type:{0}, Requests:{1}]", req.RequestType, string.Join(";", ((Requests.RequestMulti)req).Requests.Select(c => this.ToString(c)).ToArray()))); } if (req.RequestType == RingMasterRequestType.Move) { return(string.Format("Request[Type:{0}, Path:{1}, PathDst:{2}]", req.RequestType, req.Path, ((Requests.RequestMove)req).PathDst)); } return(string.Format("Request[Type:{0}, Path:{1}]", req.RequestType, req.Path)); }
/// <summary> /// Deserialize <see cref="RequestMulti"/>. /// </summary> /// <param name="callid">Id of the call</param> /// <param name="uid"><c>uid</c> associated with the request</param> /// <returns>The deserialized request</returns> private RequestMulti DeserializeRequestMulti(ulong callid, ulong uid) { ushort numReq = this.binaryReader.ReadUInt16(); IRingMasterRequest[] req = new IRingMasterRequest[numReq]; for (int i = 0; i < req.Length; i++) { this.DeserializeRingMasterRequest(callid, out req[i]); } bool completeSynchronously = this.binaryReader.ReadBoolean(); string scheduledName = null; if (this.serializationVersionUsed >= SerializationFormatVersions.Version20) { scheduledName = this.binaryReader.ReadNullableString(); } return(new RequestMulti(req, completeSynchronously, scheduledName, uid)); }
/// <summary> /// Adds the <paramref name="request"/> to <see cref="requestMap"/> with the given request ID /// </summary> /// <param name="request">Request to add</param> /// <returns>Wrapper for the request</returns> /// <remarks>This should be called while locking <see cref="requestMap"/></remarks> private RequestWrapper AddRequestToMap(IRingMasterRequest request) { ulong requestId = (ulong)Interlocked.Increment(ref this.requestId); RequestWrapper requestWrapper = new RequestWrapper(requestId, request); this.requestMap.Add(requestId, requestWrapper); if (this.newestPendingRequest != null) { requestWrapper.Previous = this.newestPendingRequest; this.newestPendingRequest.Next = requestWrapper; } else { // There are no pending requests so we should set oldestPendingRequest also this.oldestPendingRequest = requestWrapper; } this.newestPendingRequest = requestWrapper; return(requestWrapper); }
/// <summary> /// Serialize a request preamble. /// </summary> /// <param name="request">Request to serialize</param> private void SerializeRequestPreamble(IRingMasterRequest request) { this.binaryWriter.Write((ushort)request.RequestType); this.binaryWriter.Write((ulong)request.Uid); this.binaryWriter.Write((string)request.Path); this.SerializeSessionAuth(request.Auth); this.SerializeOperationOverrides(request.Overrides); if (this.versionToUse >= SerializationFormatVersions.Version17) { bool hasExecutionQueueData = request.ExecutionQueueId != Guid.Empty; this.binaryWriter.Write((bool)hasExecutionQueueData); if (hasExecutionQueueData) { this.binaryWriter.Write((Guid)request.ExecutionQueueId); this.binaryWriter.Write((int)request.ExecutionQueueTimeoutMillis); } } if (this.versionToUse >= SerializationFormatVersions.Version21) { this.binaryWriter.Write((ulong)request.TimeStreamId); } }
private void CacheInvalidate(IRingMasterClientCache cache, IRingMasterRequest req) { if (cache == null || req == null) { return; } switch (req.RequestType) { case RingMasterRequestType.GetData: case RingMasterRequestType.GetChildren: case RingMasterRequestType.GetAcl: case RingMasterRequestType.Exists: return; case RingMasterRequestType.Create: { cache.Invalidate(this.cachePrefix, req.Path); cache.Invalidate(this.cachePrefix, PrefixedClientCache.GetParent(req.Path)); break; } case RingMasterRequestType.Delete: { RequestDelete delete = req as RequestDelete; if (delete.IsCascade) { cache.Wipe(this.cachePrefix); } else { cache.Invalidate(this.cachePrefix, req.Path); cache.Invalidate(this.cachePrefix, PrefixedClientCache.GetParent(req.Path)); } break; } case RingMasterRequestType.Move: { RequestMove move = req as RequestMove; cache.Invalidate(this.cachePrefix, move.Path); cache.Invalidate(this.cachePrefix, PrefixedClientCache.GetParent(move.Path)); cache.Invalidate(this.cachePrefix, PrefixedClientCache.GetParent(move.PathDst)); break; } default: { cache.Invalidate(this.cachePrefix, req.Path); AbstractRingMasterCompoundRequest list = req as AbstractRingMasterCompoundRequest; if (list != null && list.Requests != null) { foreach (IRingMasterRequest child in list.Requests) { this.CacheInvalidate(cache, child); } } break; } } }
/// <summary> /// Serialize a <see cref="IRingMasterRequest"/> /// </summary> /// <param name="ringMasterRequest">Request to serialize</param> private void SerializeRingmasterRequest(IRingMasterRequest ringMasterRequest) { this.SerializeRequestPreamble(ringMasterRequest); switch (ringMasterRequest.RequestType) { case RingMasterRequestType.Init: this.SerializeRequestBody((RequestInit)ringMasterRequest); break; case RingMasterRequestType.SetAuth: this.SerializeRequestSetAuth((RequestSetAuth)ringMasterRequest); break; case RingMasterRequestType.Create: this.SerializeRequestCreate((RequestCreate)ringMasterRequest); break; case RingMasterRequestType.Multi: this.SerializeRequestMulti((RequestMulti)ringMasterRequest); break; case RingMasterRequestType.Move: this.SerializeRequestMove((RequestMove)ringMasterRequest); break; case RingMasterRequestType.Batch: this.SerializeRequestBatch((RequestBatch)ringMasterRequest); break; case RingMasterRequestType.Delete: this.SerializeRequestDelete((RequestDelete)ringMasterRequest); break; case RingMasterRequestType.Check: this.SerializeRequestCheck((RequestCheck)ringMasterRequest); break; case RingMasterRequestType.Sync: // Sync request has no body, so there is nothing to serialize. break; case RingMasterRequestType.Exists: this.SerializeRequestExists((RequestExists)ringMasterRequest); break; case RingMasterRequestType.GetAcl: this.SerializeRequestGetAcl((RequestGetAcl)ringMasterRequest); break; case RingMasterRequestType.GetData: this.SerializeRequestGetData((RequestGetData)ringMasterRequest); break; case RingMasterRequestType.GetChildren: this.SerializeRequestGetChildren((RequestGetChildren)ringMasterRequest); break; case RingMasterRequestType.SetAcl: this.SerializeRequestSetAcl((RequestSetAcl)ringMasterRequest); break; case RingMasterRequestType.SetData: this.SerializeRequestSetData((RequestSetData)ringMasterRequest); break; case RingMasterRequestType.GetSubtree: this.SerializeRequestGetSubtree((RequestGetSubtree)ringMasterRequest); break; case RingMasterRequestType.None: default: throw new ArgumentException("unknown type " + ringMasterRequest.GetType()); } }
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"); }
/// <summary> /// Gets the response from the cache. /// </summary> /// <param name="cache">The cache to use.</param> /// <param name="req">The request provided.</param> /// <returns>the response if cached, or null if not found</returns> private RequestResponse GetCachedResponse(IRingMasterClientCache cache, IRingMasterRequest req) { if (cache == null || req == null) { return(null); } switch (req.RequestType) { case RingMasterRequestType.GetData: { IRingMasterClientCacheDataEntry data; if (this.cache.TryGetInfo(this.cachePrefix, req.Path, CachedKind.NodeData | CachedKind.NodeStats, out data)) { RequestResponse response = new RequestResponse() { CallId = 0, ResponsePath = req.Path, ResultCode = (int)RingMasterException.Code.Ok, Content = data.Data, Stat = data.Stat, }; return(response); } break; } case RingMasterRequestType.GetChildren: { IRingMasterClientCacheDataEntry data; if (!string.IsNullOrEmpty(((RequestGetChildren)req).RetrievalCondition)) { break; } if (this.cache.TryGetInfo(this.cachePrefix, req.Path, CachedKind.NodeChildren | CachedKind.NodeStats, out data)) { RequestResponse response = new RequestResponse() { CallId = 0, ResponsePath = req.Path, ResultCode = (int)RingMasterException.Code.Ok, Content = data.Children, Stat = data.Stat, }; return(response); } break; } case RingMasterRequestType.GetAcl: { IRingMasterClientCacheDataEntry data; if (this.cache.TryGetInfo(this.cachePrefix, req.Path, CachedKind.NodeAcls | CachedKind.NodeStats, out data)) { RequestResponse response = new RequestResponse() { CallId = 0, ResponsePath = req.Path, ResultCode = (int)RingMasterException.Code.Ok, Content = data.Acls, Stat = data.Stat, }; return(response); } break; } case RingMasterRequestType.Exists: { IRingMasterClientCacheDataEntry data; if (this.cache.TryGetInfo(this.cachePrefix, req.Path, CachedKind.NodeStats, out data)) { RequestResponse response = new RequestResponse() { CallId = 0, ResponsePath = req.Path, ResultCode = (int)RingMasterException.Code.Ok, Content = data.Stat, Stat = data.Stat, }; return(response); } break; } default: { this.CacheInvalidate(cache, req); break; } } return(null); }
/// <summary> /// Processes the request in regards to the given cache object. /// </summary> /// <param name="cache">The cache object to use.</param> /// <param name="req">The request to process.</param> /// <returns><c>a response</c> if the processing was completed, <c>null</c> otherwise.</returns> private async Task <RequestResponse> ProcessCacheRequest(IRingMasterClientCache cache, IRingMasterRequest req) { if (cache != null && req != null) { RequestResponse cachedResponse = this.GetCachedResponse(cache, req); if (cachedResponse != null) { return(cachedResponse); } switch (req.RequestType) { case RingMasterRequestType.GetData: { RequestResponse resp = await this.baseHandler.Request(req); string prefix = this.cachePrefix; if (prefix != null) { cache.SetInfo(prefix, req.Path, CachedKind.NodeData | CachedKind.NodeStats, new PrefixedClientCache.DataEntry() { Data = (byte[])resp.Content, Stat = resp.Stat }); } return(resp); } case RingMasterRequestType.GetChildren: { RequestResponse resp = await this.baseHandler.Request(req); string prefix = this.cachePrefix; if (prefix != null) { RequestGetChildren gchil = req as RequestGetChildren; if (string.IsNullOrEmpty(gchil.RetrievalCondition)) { cache.SetInfo(prefix, req.Path, CachedKind.NodeChildren | CachedKind.NodeStats, new PrefixedClientCache.DataEntry() { Children = (IReadOnlyList <string>)resp.Content, Stat = resp.Stat }); } } return(resp); } case RingMasterRequestType.GetAcl: { RequestResponse resp = await this.baseHandler.Request(req); string prefix = this.cachePrefix; if (prefix != null) { cache.SetInfo(prefix, req.Path, CachedKind.NodeAcls | CachedKind.NodeStats, new PrefixedClientCache.DataEntry() { Acls = (IReadOnlyList <Acl>)resp.Content, Stat = resp.Stat }); } return(resp); } case RingMasterRequestType.Exists: { RequestResponse resp = await this.baseHandler.Request(req); string prefix = this.cachePrefix; if (prefix != null) { cache.SetInfo(prefix, req.Path, CachedKind.NodeStats, new PrefixedClientCache.DataEntry() { Stat = resp.Stat }); } return(resp); } } } return(await this.baseHandler.Request(req)); }
/// <summary> /// Process the given <see cref="IRingMasterRequest"/> /// </summary> /// <param name="request">Request to send</param> /// <returns>A task that resolves to the response sent by the server</returns> public Task <RequestResponse> Request(IRingMasterRequest request) { return(this.requestHandler.Request(request)); }
public void RequestOverlapped(IRingMasterRequest request, Action <RequestResponse, Exception> onCompletion) { onCompletion?.Invoke(this.Implementation(request), null); }
public Task <RequestResponse> Request(IRingMasterRequest request) { return(Task.FromResult(this.Implementation(request))); }
/// <summary> /// Create a new instance of the <see cref="Op"/> class that represents the given request. /// </summary> /// <param name="request"><see cref="IRingMasterRequest"/> to encapsulate</param> /// <returns>An Multi operation that encapsulates the given request</returns> public static Op Run(IRingMasterRequest request) { return(new Op(OpCode.Multi, request)); }
/// <summary> /// Initializes a new instance of the <see cref="Op"/> class with the given <see cref="IRingMasterRequest"/>. /// </summary> /// <param name="type">Type of the operation</param> /// <param name="request">The request to associate with the operation</param> private Op(OpCode type, IRingMasterRequest request) { this.OpType = type; this.Request = request; }
/// <summary> /// Deserialize <see cref="IRingMasterRequest"/> /// </summary> /// <param name="callid">Id of the call</param> /// <param name="ringMasterRequest">The ring master request.</param> /// <exception cref="System.ArgumentException">unknown type + type</exception> private void DeserializeRingMasterRequest(ulong callid, out IRingMasterRequest ringMasterRequest) { RingMasterRequestType type = (RingMasterRequestType)this.binaryReader.ReadUInt16(); ulong uid = this.binaryReader.ReadUInt64(); string path = this.binaryReader.ReadString(); ISessionAuth sessionAuth = this.DeserializeSessionAuth(); IOperationOverrides operationOverrides = this.DeserializeOperationOverrides(); Guid executionQueueId = Guid.Empty; int executionQueueTimeoutMilliseconds = 0; if (this.serializationVersionUsed >= SerializationFormatVersions.Version17) { bool hasExecutionQueueData = this.binaryReader.ReadBoolean(); if (hasExecutionQueueData) { executionQueueId = this.binaryReader.ReadGuid(); executionQueueTimeoutMilliseconds = this.binaryReader.ReadInt32(); } } ulong timeStreamId = 0; if (this.serializationVersionUsed >= SerializationFormatVersions.Version21) { timeStreamId = this.binaryReader.ReadUInt64(); } AbstractRingMasterRequest request = null; switch (type) { case RingMasterRequestType.Init: request = this.DeserializeRequestInit(uid); break; case RingMasterRequestType.SetAuth: request = this.DeserializeRequestSetAuth(uid); break; case RingMasterRequestType.Create: request = this.DeserializeRequestCreate(uid, path); break; case RingMasterRequestType.Move: request = this.DeserializeRequestMove(uid, path); break; case RingMasterRequestType.Multi: request = this.DeserializeRequestMulti(callid, uid); break; case RingMasterRequestType.Batch: request = this.DeserializeRequestBatch(callid, uid); break; case RingMasterRequestType.Delete: request = this.DeserializeRequestDelete(uid, path); break; case RingMasterRequestType.Check: request = this.DeserializeRequestCheck(uid, path); break; case RingMasterRequestType.Sync: request = this.DeserializeRequestSync(uid, path); break; case RingMasterRequestType.Exists: request = this.DeserializeRequestExists(uid, path); break; case RingMasterRequestType.GetAcl: request = this.DeserializeRequestGetAcl(uid, path); break; case RingMasterRequestType.GetData: request = this.DeserializeRequestGetData(uid, path); break; case RingMasterRequestType.GetChildren: request = this.DeserializeRequestGetChildren(uid, path); break; case RingMasterRequestType.SetData: request = this.DeserializeRequestSetData(uid, path); break; case RingMasterRequestType.SetAcl: request = this.DeserializeRequestSetAcl(uid, path); break; case RingMasterRequestType.GetSubtree: request = this.DeserializeRequestGetSubtree(uid, path); break; case RingMasterRequestType.None: default: throw new ArgumentException("unknown type " + type); } if (request != null) { request.TimeStreamId = timeStreamId; request.Auth = sessionAuth; request.Overrides = operationOverrides; request.ExecutionQueueId = executionQueueId; request.ExecutionQueueTimeoutMillis = executionQueueTimeoutMilliseconds; } ringMasterRequest = request; }
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"); }
/// <summary> /// Deserialize <see cref="IZooKeeperRequest"/> /// </summary> /// <param name="xid">the callid</param> /// <param name="type">type of the call</param> /// <param name="sessionState">The PerSession State</param> /// <param name="ringMasterRequest">The ring master request.</param> /// <exception cref="System.ArgumentException">unknown type + type</exception> /// <returns>The Zookeeper Request</returns> private IZooKeeperRequest DeserializeZooKeeperRequest(int xid, ZooKeeperRequestType type, ZkprPerSessionState sessionState, out IRingMasterRequest ringMasterRequest) { ringMasterRequest = null; switch (type) { case ZooKeeperRequestType.Notification: // "0" for Createing a session ringMasterRequest = null; return(this.DeserializeNotification(xid)); case ZooKeeperRequestType.CreateSession: ZkprProtocolMessages.CreateSession cs = this.DeserializeCreateSession(); ringMasterRequest = new RequestInit((ulong)cs.SessionId, cs.IsNullPassword ? string.Empty : cs.Password); sessionState.ConnectRecieved = true; return(cs); case ZooKeeperRequestType.Exists: ZkprProtocolMessages.Exists ex = this.DeserializeExists(xid); ringMasterRequest = new RequestExists(ex.Path, ex.Watch == false ? null : new Watcher((ulong)xid, WatcherKind.OneUse)); return(ex); case ZooKeeperRequestType.GetChildren: ZkprProtocolMessages.GetChildren gc = this.DeserializeGetChildren(xid); ringMasterRequest = new RequestGetChildren(gc.Path, gc.Watch == false ? null : new Watcher((ulong)xid, WatcherKind.OneUse), null); return(gc); case ZooKeeperRequestType.GetChildren2: ZkprProtocolMessages.GetChildren2 gc2 = this.DeserializeGetChildren2(xid); ringMasterRequest = new RequestGetChildren(gc2.Path, gc2.Watch == false ? null : new Watcher((ulong)xid, WatcherKind.OneUse), null); return(gc2); case ZooKeeperRequestType.GetData: ZkprProtocolMessages.GetData gd = this.DeserializeGetData(xid); ringMasterRequest = new RequestGetData(gd.Path, RequestGetData.GetDataOptions.None, gd.Watch == false ? null : new Watcher((ulong)xid, WatcherKind.OneUse)); return(gd); case ZooKeeperRequestType.Create: ZkprProtocolMessages.Create cr = this.DeserializeCreate(xid); IReadOnlyList <Acl> acls = this.TranslateZkprAclListToRMAclList(cr.Acls); CreateMode cm = this.TranslateZkprCreatFlagsToRmCreateMode(cr.Flags); ringMasterRequest = new RequestCreate(cr.Path, cr.Data, acls, cm); return(cr); case ZooKeeperRequestType.Create2: ZkprProtocolMessages.Create2 cr2 = this.DeserializeCreate2(xid); IReadOnlyList <Acl> acls2 = this.TranslateZkprAclListToRMAclList(cr2.Acls); CreateMode cm2 = this.TranslateZkprCreatFlagsToRmCreateMode(cr2.Flags); ringMasterRequest = new RequestCreate(cr2.Path, cr2.Data, acls2, cm2); return(cr2); case ZooKeeperRequestType.SetData: ZkprProtocolMessages.SetData sd = this.DeserializeSetData(xid); ringMasterRequest = new RequestSetData(sd.Path, sd.Data, sd.Version); return(sd); case ZooKeeperRequestType.Delete: ZkprProtocolMessages.Delete dl = this.DeserializeDelete(xid); ringMasterRequest = new RequestDelete(dl.Path, dl.Version, false); return(dl); case ZooKeeperRequestType.Ping: ringMasterRequest = null; return(this.DeserializePing(xid)); case ZooKeeperRequestType.CloseSession: ringMasterRequest = null; sessionState.ConnectRecieved = false; // Renegotiate the CreateSession return(this.DeserializeCloseSession(xid)); case ZooKeeperRequestType.GetACL: ZkprProtocolMessages.GetACL ga = this.DeserializeGetACL(xid); ringMasterRequest = new RequestGetAcl(ga.Path, null); return(ga); case ZooKeeperRequestType.SetACL: ZkprProtocolMessages.SetACL sa = this.DeserializeSetACL(xid); IReadOnlyList <Acl> sa_acls = this.TranslateZkprAclListToRMAclList(sa.Acls); ringMasterRequest = new RequestSetAcl(sa.Path, sa_acls, sa.Version); return(sa); case ZooKeeperRequestType.Multi: ZkprProtocolMessages.Multi mu = this.DeserializeMulti(xid); IReadOnlyList <Op> rmOps = this.TranslateZkprOpsListToRmOpsList(mu.Ops); ringMasterRequest = new RequestMulti(rmOps, false); return(mu); case ZooKeeperRequestType.Auth: ZkprProtocolMessages.Auth au = this.DeserializeAuth(xid); ringMasterRequest = new RequestSetAuth(au.RmAuthId); return(au); case ZooKeeperRequestType.Check: case ZooKeeperRequestType.Sync: case ZooKeeperRequestType.Reconfig: case ZooKeeperRequestType.SetWatches: case ZooKeeperRequestType.RemoveWatches: case ZooKeeperRequestType.CreateContainer: case ZooKeeperRequestType.DeleteContainer: case ZooKeeperRequestType.Sasl: case ZooKeeperRequestType.Error: default: break; } return(null); }