public void TestMessageChecksum() { byte[] bytes = new byte[] { 4, 6, 4, 6, 6, 46, 6, 34, 64, 2, 64, 62, 47, 27, 247, 4, 6, 4, 6, 6, 46, 6, 34, 64, 2, 64, 62, 47, 27, 247 }; byte[] bigBytes = new byte[8 * 1024]; Array.Copy(bytes, bigBytes, bytes.Length); var calculatedChecksum = CoderHelper.CalculateChecksum(bytes, 0, bytes.Length); var newLength = CoderHelper.AddChecksum(bigBytes, 0, bytes.Length) + bytes.Length; byte checksumInBigBytes = bigBytes[bytes.Length]; Assert.AreEqual(checksumInBigBytes, calculatedChecksum); var writer = new MessageStreamWriter(); var reader = new MessageStreamReader(); var loginRequest = new LoginRequest() { accessToken = "alsdjflakjsdf", username = "******" }; var matchRequest = new MatchRequest() { value1 = 1, value2 = 2, value3 = 3, value4 = 4 }; writer.Write(loginRequest); writer.Write(matchRequest); writer.Use((buffer, len) => { reader.Add(buffer, len); var message = reader.Decode(); Assert.IsTrue(message.Value.Is(200)); Assert.AreEqual(loginRequest, message.Value.Parse <LoginRequest>()); message = reader.Decode(); Assert.IsTrue(message.Value.Is(201)); Assert.AreEqual(matchRequest, message.Value.Parse <MatchRequest>()); writer.DidWrite(len); }); writer.Write(loginRequest); writer.Write(matchRequest); writer.currentBuffer[0] = 23; writer.Use((buffer, len) => { reader.Add(buffer, len); var message = reader.Decode(); Assert.IsFalse(message.HasValue); Assert.IsTrue(message == null); message = reader.Decode(); Assert.IsTrue(message.Value.Is(201)); Assert.AreEqual(matchRequest, message.Value.Parse <MatchRequest>()); writer.DidWrite(len); }); }
public void Serialize(MessageStreamWriter w, Hash value, int rank) { if (rank > 256) { throw new FormatException(); } w.Write((ulong)value.Algorithm); w.Write(value.Value); }
private void Cancel(int id) { var messageStream = new RecyclableMemoryStream(_bufferManager); var writer = new MessageStreamWriter(messageStream, _bufferManager); writer.Write((ulong)AmoebaFunctionType.Cancel); writer.Write((ulong)id); messageStream.Seek(0, SeekOrigin.Begin); _messagingManager.Send(messageStream); }
public void TestMultithreadReadAndWrite() { var loginRequest = new LoginRequest() { accessToken = "askldfaljksdf", username = "******" }; var reader = new MessageStreamReader(); var writer = new MessageStreamWriter(); for (int reading = 0; reading < 50; reading++) { for (int write = 0; write < 2; write++) { writer.Write(loginRequest); Logger.Log($"Did Write loginRequest {write * reading}"); } writer.Use((buffer, len) => { Logger.Log($"Using buffer with len: {len}"); reader.Add(buffer, len); MessageContainer?message = null; while ((message = reader.Decode()).HasValue) { Logger.Log($"Decoded message: {message.Value.type}"); Assert.AreEqual(loginRequest, message.Value.Parse <LoginRequest>()); } writer.DidWrite(len); Logger.Log($"Did Write len: {len}"); }); } Assert.AreEqual(0, writer.currentBufferLength); Assert.AreEqual(0, reader.currentBufferLength); }
public void ManyMessagesShouldNotTriggerSizeAlert() { int messageSize = TestUtil.GetAllSet().SerializedSize; // Enough messages to trigger the alert unless we've reset the size // Note that currently we need to make this big enough to copy two whole buffers, // as otherwise when we refill the buffer the second type, the alert triggers instantly. int correctCount = (CodedInputStream.BufferSize * 2) / messageSize + 1; using (MemoryStream stream = new MemoryStream()) { MessageStreamWriter<TestAllTypes> writer = new MessageStreamWriter<TestAllTypes>(stream); for (int i = 0; i < correctCount; i++) { writer.Write(TestUtil.GetAllSet()); } writer.Flush(); stream.Position = 0; int count = 0; foreach (var message in MessageStreamIterator<TestAllTypes>.FromStreamProvider(() => stream) .WithSizeLimit(CodedInputStream.BufferSize * 2)) { count++; TestUtil.AssertAllFieldsSet(message); } Assert.AreEqual(correctCount, count); } }
private void PersistTopology() { byte[] buffer; var topology = master.Topology.GetTopology(); using (var stream = new MemoryStream()) { var writer = new MessageStreamWriter <TopologyResultMessage>(stream); writer.Write(topology); writer.Flush(); buffer = stream.ToArray(); } hashTable.Batch(actions => { var values = actions.Get(new GetRequest { Key = Constants.Topology }); actions.Put(new PutRequest { Key = Constants.Topology, ParentVersions = values.Select(x => x.Version).ToArray(), Bytes = buffer, IsReadOnly = true }); actions.Commit(); }); }
private void HandleReplicateNextPage(StorageMessageUnion wrapper, MessageStreamWriter <StorageMessageUnion> writer) { var replicationResult = replication.ReplicateNextPage( wrapper.ReplicateNextPageRequest.ReplicationEndpoint.GetNodeEndpoint(), wrapper.ReplicateNextPageRequest.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.ReplicateNextPageRequest.Segment ); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.ReplicateNextPageResponse, ReplicateNextPageResponse = new ReplicateNextPageResponseMessage.Builder() { Done = replicationResult.Done, RemoveRequestsList = { replicationResult.RemoveRequests.Select(x => x.GetRemoveRequest()), }, PutRequestsList = { replicationResult.PutRequests.Select(x => x.GetPutRequest()) } }.Build() }.Build()); }
public void ThreeMessages() { NestedMessage message1 = new NestedMessage.Builder { Bb = 5 }.Build(); NestedMessage message2 = new NestedMessage.Builder { Bb = 1500 }.Build(); NestedMessage message3 = new NestedMessage.Builder().Build(); byte[] data; using (MemoryStream stream = new MemoryStream()) { MessageStreamWriter<NestedMessage> writer = new MessageStreamWriter<NestedMessage>(stream); writer.Write(message1); writer.Write(message2); writer.Write(message3); writer.Flush(); data = stream.ToArray(); } TestUtil.AssertEqualBytes(ThreeMessageData, data); }
private void HandleTopologyUpdate(MessageStreamWriter <StorageMessageUnion> writer) { node.UpdateTopology(); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.TopologyUpdated }.Build()); }
public Stream GetCashStream(string signature) { var bufferManager = BufferManager.Instance; var signatureStream = new RecyclableMemoryStream(bufferManager); { var writer = new MessageStreamWriter(signatureStream, bufferManager); writer.Write((ulong)5); writer.Write(signature); signatureStream.Seek(0, SeekOrigin.Begin); } var target = new MulticastMetadata(this.Type, this.Tag, this.CreationTime, this.Metadata, (Cash)null, (Certificate)null); return(new UniteStream(target.Export(bufferManager), signatureStream)); }
private void HandleGetToplogy(MessageStreamWriter <MasterMessageUnion> writer) { var topology = master.GetTopology(); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.GetTopologyResult, Topology = topology.GetTopology() }.Build()); }
public PutResult[] Put(int topologyVersion, params ExtendedPutRequest[] valuesToAdd) { writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.PutRequests, TopologyVersion = topologyVersion, PutRequestsList = { valuesToAdd.Select(x => x.GetPutRequest()) } }.Build()); writer.Flush(); stream.Flush(); var union = ReadReply(StorageMessageType.PutResponses); return(union.PutResponsesList.Select(x => new PutResult { ConflictExists = x.ConflictExists, Version = new PersistentHashTable.ValueVersion { InstanceId = new Guid(x.Version.InstanceId.ToByteArray()), Number = x.Version.Number } }).ToArray()); }
private (int, WaitQueue <ResponseInfo>) Send <TArgument>(AmoebaFunctionType type, TArgument argument) { int id = this.CreateId(); var queue = new WaitQueue <ResponseInfo>(); _queueMap.Add(id, queue); var messageStream = new RecyclableMemoryStream(_bufferManager); var writer = new MessageStreamWriter(messageStream, _bufferManager); writer.Write((ulong)type); writer.Write((ulong)id); Stream valueStream = null; if (argument != null) { try { valueStream = new RecyclableMemoryStream(_bufferManager); JsonUtils.Save(valueStream, argument); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } throw; } } messageStream.Seek(0, SeekOrigin.Begin); _messagingManager.Send(new UniteStream(messageStream, valueStream)); return(id, queue); }
private void HandleGaveUp(MasterMessageUnion wrapper, MessageStreamWriter <MasterMessageUnion> writer) { master.GaveUp(new NodeEndpoint { Async = new Uri(wrapper.GaveUp.Endpoint.Async), Sync = new Uri(wrapper.GaveUp.Endpoint.Sync) }, wrapper.GaveUp.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.GaveUp.GaveUpSegmentsList.ToArray()); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.GaveUpResponse }.Build()); }
private void HandlePut(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter <StorageMessageUnion> writer) { var puts = wrapper.PutRequestsList.Select(x => x.GetPutRequest()).ToArray(); var results = storage.Put(topologyVersion, puts); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.PutResponses, TopologyVersion = topologyVersion, PutResponsesList = { results.Select(x => x.GetPutResponse()) } }.Build()); }
private void HandleAssignEmpty(StorageMessageUnion wrapper, MessageStreamWriter <StorageMessageUnion> writer) { var segments = replication.AssignAllEmptySegments( wrapper.AssignAllEmptySegmentsRequest.ReplicationEndpoint.GetNodeEndpoint(), wrapper.AssignAllEmptySegmentsRequest.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.AssignAllEmptySegmentsRequest.SegmentsList.ToArray() ); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.AssignAllEmptySegmentsResponse, AssignAllEmptySegmentsResponse = new AssignAllEmptySegmentsResponseMessage.Builder { AssignedSegmentsList = { segments } }.Build() }.Build()); }
private void HandleGet(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter <StorageMessageUnion> writer) { var values = storage.Get(topologyVersion, wrapper.GetRequestsList.Select(x => x.GetGetRequest()).ToArray() ); var reply = new StorageMessageUnion.Builder { Type = StorageMessageType.GetResponses, TopologyVersion = wrapper.TopologyVersion, GetResponsesList = { values.Select(x => x.GetGetResponse()) } }; writer.Write(reply.Build()); }
private void HandleJoin(MasterMessageUnion wrapper, MessageStreamWriter <MasterMessageUnion> writer) { var endpoint = wrapper.JoinRequest.EndpointJoining; var segments = master.Join(new NodeEndpoint { Async = new Uri(endpoint.Async), Sync = new Uri(endpoint.Sync) }); var joinResponse = new JoinResponseMessage.Builder { SegmentsList = { segments.Select(x => x.GetSegment()) } }; writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.JoinResult, JoinResponse = joinResponse.Build() }.Build()); }
private void HandleRemove(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter <StorageMessageUnion> writer) { var requests = wrapper.RemoveRequestsList.Select(x => x.GetRemoveRequest()).ToArray(); var removed = storage.Remove(topologyVersion, requests); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.RemoveResponses, TopologyVersion = topologyVersion, RemoveResponesList = { removed.Select(x => new RemoveResponseMessage.Builder { WasRemoved = x }.Build()) } }.Build()); }
private void HandlePut(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter<StorageMessageUnion> writer) { var puts = wrapper.PutRequestsList.Select(x => x.GetPutRequest()).ToArray(); var results = storage.Put(topologyVersion, puts); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.PutResponses, TopologyVersion = topologyVersion, PutResponsesList = { results.Select(x=>x.GetPutResponse()) } }.Build()); }
private void HandleGet(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter<StorageMessageUnion> writer) { var values = storage.Get(topologyVersion, wrapper.GetRequestsList.Select(x => x.GetGetRequest()).ToArray() ); var reply = new StorageMessageUnion.Builder { Type = StorageMessageType.GetResponses, TopologyVersion = wrapper.TopologyVersion, GetResponsesList = { values.Select(x=> x.GetGetResponse()) } }; writer.Write(reply.Build()); }
private void HandleAssignEmpty(StorageMessageUnion wrapper, MessageStreamWriter<StorageMessageUnion> writer) { var segments = replication.AssignAllEmptySegments( wrapper.AssignAllEmptySegmentsRequest.ReplicationEndpoint.GetNodeEndpoint(), wrapper.AssignAllEmptySegmentsRequest.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.AssignAllEmptySegmentsRequest.SegmentsList.ToArray() ); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.AssignAllEmptySegmentsResponse, AssignAllEmptySegmentsResponse = new AssignAllEmptySegmentsResponseMessage.Builder { AssignedSegmentsList = { segments } }.Build() }.Build()); }
public void TestPartialStreamingDecoding() { var firstToken = "asldkfjalksdjfalkjsdf"; var username = "******"; var secondToken = "asdlkfalksjdgklashdioohweg"; var ip = "10.0.0.1"; var port = (short)6109; var loginRequest = new LoginRequest { accessToken = firstToken, username = username }; var matchRequest = new MatchRequest(); var connectRequest = new ConnectGameInstanceResponse { token = secondToken, ip = ip, port = port }; var encoder = new MessageStreamWriter(); List <byte> data = new List <byte>(); encoder.Write(loginRequest); encoder.Use((buffer, count) => data.AddRange(buffer, count)); encoder.Write(matchRequest); encoder.Use((buffer, count) => data.AddRange(buffer, count)); encoder.Write(connectRequest); encoder.Use((buffer, count) => data.AddRange(buffer, count)); var decoder = new MessageStreamReader(); this.Measure(() => { var position = 0; do { var x = data.GetRange(position, 1).ToArray(); decoder.Add(x, x.Length); var container = decoder.Decode(); if (container.HasValue) { if (container.Value.Is(200)) // LoginRequest { var message = container.Value.Parse <LoginRequest>(); Assert.AreEqual(message.accessToken, firstToken); Assert.AreEqual(message.username, username); } else if (container.Value.Is(201)) // MatchRequest { var message = container.Value.Parse <MatchRequest>(); Assert.AreNotEqual(message, null); } else if (container.Value.Is(202)) // ConnectGameInstanceResponse { var message = container.Value.Parse <ConnectGameInstanceResponse>(); Assert.AreEqual(message.ip, ip); Assert.AreEqual(message.port, port); Assert.AreEqual(message.token, secondToken); } } position += 1; } while (position < data.Count); }, "Partial Stream Decoding"); }
private void OnBeginAcceptTcpClient(IAsyncResult result) { TcpClient client; try { client = listener.EndAcceptTcpClient(result); listener.BeginAcceptTcpClient(OnBeginAcceptTcpClient, null); } catch (ObjectDisposedException) { return; } catch (InvalidOperationException) { return; } try { using (client) using (var stream = client.GetStream()) { var writer = new MessageStreamWriter <StorageMessageUnion>(stream); try { foreach (var wrapper in MessageStreamIterator <StorageMessageUnion> .FromStreamProvider(() => new UndisposableStream(stream))) { log.DebugFormat("Got message {0}", wrapper.Type); switch (wrapper.Type) { case StorageMessageType.GetRequests: HandleGet(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.PutRequests: HandlePut(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.RemoveRequests: HandleRemove(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.AssignAllEmptySegmentsRequest: HandleAssignEmpty(wrapper, writer); break; case StorageMessageType.ReplicateNextPageRequest: HandleReplicateNextPage(wrapper, writer); break; case StorageMessageType.UpdateTopology: HandleTopologyUpdate(writer); break; default: throw new InvalidOperationException("Message type was not understood: " + wrapper.Type); } writer.Flush(); stream.Flush(); } } catch (IOException) { // disconnected, so nothing else to do } catch (SeeOtherException e) { writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.SeeOtherError, SeeOtherError = new SeeOtherErrorMessage.Builder { Other = e.Endpoint.GetNodeEndpoint() }.Build() }.Build()); writer.Flush(); stream.Flush(); } catch (TopologyVersionDoesNotMatchException) { writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.TopologyChangedError, }.Build()); writer.Flush(); stream.Flush(); } catch (Exception e) { log.Warn("Error performing request", e); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.StorageErrorResult, Exception = new ErrorMessage.Builder { Message = e.ToString() }.Build() }.Build()); writer.Flush(); stream.Flush(); } } } catch (Exception e) { log.Warn("Error when processing request to storage", e); } }
private void _messagingManager_ReceiveEvent(Stream requestStream) { var reader = new MessageStreamReader(new WrapperStream(requestStream), _bufferManager); { var type = (AmoebaFunctionType)reader.GetUInt64(); int id = (int)reader.GetUInt64(); if (type == AmoebaFunctionType.Exit) { SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); _tokenSource.Cancel(); } else if (type == AmoebaFunctionType.Cancel) { if (_tasks.TryGetValue(id, out var responseTask)) { responseTask.Stop(); } } else { var responseTask = ResponseTask.Create((token) => { try { switch (type) { case AmoebaFunctionType.GetReport: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Report); break; } case AmoebaFunctionType.GetNetworkConnectionReports: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetNetworkConnectionReports()); break; } case AmoebaFunctionType.GetCacheContentReports: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetCacheContentReports()); break; } case AmoebaFunctionType.GetDownloadContentReports: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetDownloadContentReports()); break; } case AmoebaFunctionType.GetConfig: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Config); break; } case AmoebaFunctionType.SetConfig: { var config = JsonUtils.Load <ServiceConfig>(requestStream); _serviceManager.SetConfig(config); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.SetCloudLocations: { var cloudLocations = JsonUtils.Load <Location[]>(requestStream); _serviceManager.SetCloudLocations(cloudLocations); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.GetSize: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Size); break; } case AmoebaFunctionType.Resize: { long size = JsonUtils.Load <long>(requestStream); _serviceManager.Resize(size); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.CheckBlocks: { _serviceManager.CheckBlocks(new Action <CheckBlocksProgressReport>((report) => { SendResponse(AmoebaFunctionResponseType.Output, id, report); }), token).Wait(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.AddContent: { var arguments = JsonUtils.Load <(string, DateTime)>(requestStream); var result = _serviceManager.AddContent(arguments.Item1, arguments.Item2, token).Result; SendResponse(AmoebaFunctionResponseType.Result, id, result); break; } case AmoebaFunctionType.RemoveContent: { string path = JsonUtils.Load <string>(requestStream); _serviceManager.RemoveContent(path); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.Diffusion: { string path = JsonUtils.Load <string>(requestStream); _serviceManager.DiffuseContent(path); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.AddDownload: { var arguments = JsonUtils.Load <(Metadata, string, long)>(requestStream); _serviceManager.AddDownload(arguments.Item1, arguments.Item2, arguments.Item3); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.RemoveDownload: { var arguments = JsonUtils.Load <(Metadata, string)>(requestStream); _serviceManager.RemoveDownload(arguments.Item1, arguments.Item2); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.ResetDownload: { var arguments = JsonUtils.Load <(Metadata, string)>(requestStream); _serviceManager.ResetDownload(arguments.Item1, arguments.Item2); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.SetProfile: { var arguments = JsonUtils.Load <(ProfileContent, DigitalSignature)>(requestStream); _serviceManager.SetProfile(arguments.Item1, arguments.Item2, token).Wait(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.SetStore: { var arguments = JsonUtils.Load <(StoreContent, DigitalSignature)>(requestStream); _serviceManager.SetStore(arguments.Item1, arguments.Item2, token).Wait(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.SetUnicastCommentMessage: { var arguments = JsonUtils.Load <(Signature, CommentContent, AgreementPublicKey, DigitalSignature)>(requestStream); _serviceManager.SetUnicastCommentMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.SetMulticastCommentMessage: { var arguments = JsonUtils.Load <(Tag, CommentContent, DigitalSignature, TimeSpan)>(requestStream); _serviceManager.SetMulticastCommentMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.GetProfile: { var signature = JsonUtils.Load <Signature>(requestStream); var result = _serviceManager.GetProfile(signature, token).Result; SendResponse(AmoebaFunctionResponseType.Result, id, result); break; } case AmoebaFunctionType.GetStore: { var signature = JsonUtils.Load <Signature>(requestStream); var result = _serviceManager.GetStore(signature, token).Result; SendResponse(AmoebaFunctionResponseType.Result, id, result); break; } case AmoebaFunctionType.GetUnicastCommentMessages: { var arguments = JsonUtils.Load <(Signature, AgreementPrivateKey)>(requestStream); var result = _serviceManager.GetUnicastCommentMessages(arguments.Item1, arguments.Item2, token).Result; SendResponse(AmoebaFunctionResponseType.Result, id, result); break; } case AmoebaFunctionType.GetMulticastCommentMessages: { var tag = JsonUtils.Load <Tag>(requestStream); var result = _serviceManager.GetMulticastCommentMessages(tag, token).Result; SendResponse(AmoebaFunctionResponseType.Result, id, result); break; } case AmoebaFunctionType.GetState: { SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.State); break; } case AmoebaFunctionType.Start: { _serviceManager.Start(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.Stop: { _serviceManager.Stop(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.Load: { _serviceManager.Load(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } case AmoebaFunctionType.Save: { _serviceManager.Save(); SendResponse(AmoebaFunctionResponseType.Result, id, (object)null); break; } } } catch (OperationCanceledException) { SendResponse(AmoebaFunctionResponseType.Cancel, id, (object)null); } catch (Exception e) { Log.Error(string.Format("Rpc Error: {0}", type.ToString())); Log.Error(e); var argument = new AmoebaErrorMessage(e.GetType().ToString(), e.Message, e.StackTrace?.ToString()); SendResponse(AmoebaFunctionResponseType.Error, id, argument); } finally { requestStream.Dispose(); _tasks.Remove(id); } }); _tasks.Add(id, responseTask); responseTask.Start(); } } void SendResponse <T>(AmoebaFunctionResponseType type, int id, T value) { var messageStream = new RecyclableMemoryStream(_bufferManager); var writer = new MessageStreamWriter(messageStream, _bufferManager); writer.Write((ulong)type); writer.Write((ulong)id); Stream valueStream = null; if (value != null) { try { valueStream = new RecyclableMemoryStream(_bufferManager); JsonUtils.Save(valueStream, value); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } return; } } messageStream.Seek(0, SeekOrigin.Begin); _messagingManager.Send(new UniteStream(messageStream, valueStream)); } }
private void OnAcceptTcpClient(IAsyncResult result) { TcpClient client; try { client = listener.EndAcceptTcpClient(result); } catch (ObjectDisposedException) { return; } //this is done intentionally in a single threaded fashion //the master is not a hot spot and it drastically simplify our life //to avoid having to do multi threaded stuff here //all calls to the master are also very short try { using (client) using (var stream = client.GetStream()) { var writer = new MessageStreamWriter <MasterMessageUnion>(stream); foreach (var wrapper in MessageStreamIterator <MasterMessageUnion> .FromStreamProvider(() => stream)) { try { log.DebugFormat("Accepting message from {0} - {1}", client.Client.RemoteEndPoint, wrapper.Type); switch (wrapper.Type) { case MasterMessageType.GetTopologyRequest: HandleGetToplogy(writer); break; case MasterMessageType.JoinRequest: HandleJoin(wrapper, writer); break; case MasterMessageType.CaughtUpRequest: HandleCatchUp(wrapper, writer); break; case MasterMessageType.GaveUpRequest: HandleGaveUp(wrapper, writer); break; default: throw new ArgumentOutOfRangeException(); } writer.Flush(); stream.Flush(); } catch (Exception e) { log.Warn("Error performing request", e); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.MasterErrorResult, Exception = new ErrorMessage.Builder { Message = e.ToString() }.Build() }.Build()); writer.Flush(); stream.Flush(); } } } } catch (Exception e) { log.Warn("Error when dealing with a request (or could not send error details)", e); } finally { try { listener.BeginAcceptTcpClient(OnAcceptTcpClient, null); } catch (InvalidOperationException) { //the listener was closed } } }
private void HandleCatchUp(MasterMessageUnion wrapper, MessageStreamWriter<MasterMessageUnion> writer) { master.CaughtUp(new NodeEndpoint { Async = new Uri(wrapper.CaughtUp.Endpoint.Async), Sync = new Uri(wrapper.CaughtUp.Endpoint.Sync) }, wrapper.CaughtUp.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.CaughtUp.CaughtUpSegmentsList.ToArray()); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.CaughtUpResponse }.Build()); }
private void PersistTopology() { byte[] buffer; var topology = master.Topology.GetTopology(); using (var stream = new MemoryStream()) { var writer = new MessageStreamWriter<TopologyResultMessage>(stream); writer.Write(topology); writer.Flush(); buffer = stream.ToArray(); } hashTable.Batch(actions => { var values = actions.Get(new GetRequest { Key = Constants.Topology }); actions.Put(new PutRequest { Key = Constants.Topology, ParentVersions = values.Select(x => x.Version).ToArray(), Bytes = buffer, IsReadOnly = true }); actions.Commit(); }); }
private void OnAcceptTcpClient(IAsyncResult result) { TcpClient client; try { client = listener.EndAcceptTcpClient(result); } catch (ObjectDisposedException) { return; } //this is done intentionally in a single threaded fashion //the master is not a hot spot and it drastically simplify our life //to avoid having to do multi threaded stuff here //all calls to the master are also very short try { using (client) using (var stream = client.GetStream()) { var writer = new MessageStreamWriter<MasterMessageUnion>(stream); foreach (var wrapper in MessageStreamIterator<MasterMessageUnion>.FromStreamProvider(() => stream)) { try { log.DebugFormat("Accepting message from {0} - {1}", client.Client.RemoteEndPoint, wrapper.Type); switch (wrapper.Type) { case MasterMessageType.GetTopologyRequest: HandleGetToplogy(writer); break; case MasterMessageType.JoinRequest: HandleJoin(wrapper, writer); break; case MasterMessageType.CaughtUpRequest: HandleCatchUp(wrapper, writer); break; case MasterMessageType.GaveUpRequest: HandleGaveUp(wrapper, writer); break; default: throw new ArgumentOutOfRangeException(); } writer.Flush(); stream.Flush(); } catch (Exception e) { log.Warn("Error performing request", e); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.MasterErrorResult, Exception = new ErrorMessage.Builder { Message = e.ToString() }.Build() }.Build()); writer.Flush(); stream.Flush(); } } } } catch (Exception e) { log.Warn("Error when dealing with a request (or could not send error details)", e); } finally { try { listener.BeginAcceptTcpClient(OnAcceptTcpClient, null); } catch (InvalidOperationException) { //the listener was closed } } }
private void HandleTopologyUpdate(MessageStreamWriter<StorageMessageUnion> writer) { node.UpdateTopology(); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.TopologyUpdated }.Build()); }
private void HandleRemove(StorageMessageUnion wrapper, int topologyVersion, MessageStreamWriter<StorageMessageUnion> writer) { var requests = wrapper.RemoveRequestsList.Select(x => x.GetRemoveRequest()).ToArray(); var removed = storage.Remove(topologyVersion, requests); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.RemoveResponses, TopologyVersion = topologyVersion, RemoveResponesList = { removed.Select(x => new RemoveResponseMessage.Builder { WasRemoved = x }.Build()) } }.Build()); }
private void HandleReplicateNextPage(StorageMessageUnion wrapper, MessageStreamWriter<StorageMessageUnion> writer) { var replicationResult = replication.ReplicateNextPage( wrapper.ReplicateNextPageRequest.ReplicationEndpoint.GetNodeEndpoint(), wrapper.ReplicateNextPageRequest.Type == ReplicationType.Backup ? Internal.ReplicationType.Backup : Internal.ReplicationType.Ownership, wrapper.ReplicateNextPageRequest.Segment ); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.ReplicateNextPageResponse, ReplicateNextPageResponse = new ReplicateNextPageResponseMessage.Builder() { Done = replicationResult.Done, RemoveRequestsList = { replicationResult.RemoveRequests.Select(x=>x.GetRemoveRequest()), }, PutRequestsList = { replicationResult.PutRequests.Select(x=>x.GetPutRequest()) } }.Build() }.Build()); }
private void HandleGetToplogy(MessageStreamWriter<MasterMessageUnion> writer) { var topology = master.GetTopology(); writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.GetTopologyResult, Topology = topology.GetTopology() }.Build()); }
private void OnBeginAcceptTcpClient(IAsyncResult result) { TcpClient client; try { client = listener.EndAcceptTcpClient(result); listener.BeginAcceptTcpClient(OnBeginAcceptTcpClient, null); } catch (ObjectDisposedException) { return; } catch (InvalidOperationException) { return; } try { using (client) using (var stream = client.GetStream()) { var writer = new MessageStreamWriter<StorageMessageUnion>(stream); try { foreach (var wrapper in MessageStreamIterator<StorageMessageUnion>.FromStreamProvider(() => new UndisposableStream(stream))) { log.DebugFormat("Got message {0}", wrapper.Type); switch (wrapper.Type) { case StorageMessageType.GetRequests: HandleGet(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.PutRequests: HandlePut(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.RemoveRequests: HandleRemove(wrapper, wrapper.TopologyVersion.Value, writer); break; case StorageMessageType.AssignAllEmptySegmentsRequest: HandleAssignEmpty(wrapper, writer); break; case StorageMessageType.ReplicateNextPageRequest: HandleReplicateNextPage(wrapper, writer); break; case StorageMessageType.UpdateTopology: HandleTopologyUpdate(writer); break; default: throw new InvalidOperationException("Message type was not understood: " + wrapper.Type); } writer.Flush(); stream.Flush(); } } catch(IOException) { // disconnected, so nothing else to do } catch (SeeOtherException e) { writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.SeeOtherError, SeeOtherError = new SeeOtherErrorMessage.Builder { Other = e.Endpoint.GetNodeEndpoint() }.Build() }.Build()); writer.Flush(); stream.Flush(); } catch (TopologyVersionDoesNotMatchException) { writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.TopologyChangedError, }.Build()); writer.Flush(); stream.Flush(); } catch (Exception e) { log.Warn("Error performing request", e); writer.Write(new StorageMessageUnion.Builder { Type = StorageMessageType.StorageErrorResult, Exception = new ErrorMessage.Builder { Message = e.ToString() }.Build() }.Build()); writer.Flush(); stream.Flush(); } } } catch (Exception e) { log.Warn("Error when processing request to storage", e); } }
private void HandleJoin(MasterMessageUnion wrapper, MessageStreamWriter<MasterMessageUnion> writer) { var endpoint = wrapper.JoinRequest.EndpointJoining; var segments = master.Join(new NodeEndpoint { Async = new Uri(endpoint.Async), Sync = new Uri(endpoint.Sync) }); var joinResponse = new JoinResponseMessage.Builder { SegmentsList = { segments.Select(x => x.GetSegment()) } }; writer.Write(new MasterMessageUnion.Builder { Type = MasterMessageType.JoinResult, JoinResponse = joinResponse.Build() }.Build()); }