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 (int, WaitQueue <ResponseInfo>) Send <TArgument>(AmoebaRequestType type, TArgument argument) { int id = this.CreateId(); var queue = new WaitQueue <ResponseInfo>(); _queueMap.Add(id, queue); using (var writer = new ItemStreamWriter(_bufferManager)) { writer.Write((uint)type); writer.Write((uint)id); Stream valueStream = null; if (argument != null) { try { valueStream = new BufferStream(_bufferManager); JsonUtils.Save(valueStream, argument); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } throw; } } _messagingManager.Send(new UniteStream(writer.GetStream(), valueStream)); } return(id, queue); }
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)); } }