public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (_clientWebSocket.State != WebSocketState.Open) { throw new InvalidOperationException("The connection was not initialized. Call OpenAsync first."); } var envelopeJson = _envelopeSerializer.Serialize(envelope); if (_traceWriter != null && _traceWriter.IsEnabled) { await _traceWriter.TraceAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); } var jsonBytes = Encoding.UTF8.GetBytes(envelopeJson); await _sendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { await _clientWebSocket.SendAsync(new ArraySegment <byte>(jsonBytes), WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false); } finally { _sendSemaphore.Release(); } }
public async Task ExecuteAsync(IContext context, JObject settings, CancellationToken cancellationToken) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (settings == null) { throw new ArgumentNullException(nameof(settings), $"The settings are required for '{nameof(ProcessCommandAction)}' action"); } string variable = null; if (settings.TryGetValue(nameof(variable), out var variableToken)) { variable = variableToken.ToString().Trim('"'); } var command = settings.ToObject <Command>(LimeSerializerContainer.Serializer); command.Id = EnvelopeId.NewId(); var resultCommand = await _sender.ProcessCommandAsync(command, cancellationToken); if (string.IsNullOrWhiteSpace(variable)) { return; } var resultCommandJson = _envelopeSerializer.Serialize(resultCommand); await context.SetVariableAsync(variable, resultCommandJson, cancellationToken); }
/// <summary> /// Sends an envelope to /// the connected node /// </summary> /// <param name="envelope">Envelope to be transported</param> /// <param name="cancellationToken"></param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException("envelope"); } if (_stream == null || !_stream.CanWrite) { throw new InvalidOperationException("Invalid stream state. Call OpenAsync first."); } var envelopeJson = _envelopeSerializer.Serialize(envelope); if (_traceWriter != null && _traceWriter.IsEnabled) { await _traceWriter.TraceAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); } var jsonBytes = Encoding.UTF8.GetBytes(envelopeJson); await _sendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { await _stream.WriteAsync(jsonBytes, 0, jsonBytes.Length, cancellationToken).ConfigureAwait(false); } finally { _sendSemaphore.Release(); } }
private async Task SendEnvelopeAsync(Envelope envelope, CancellationToken cancellationToken) { EnsureNotSent(); await _sendSemaphore.WaitAsync(cancellationToken); try { EnsureNotSent(); _envelopeSent = true; _context.Response.StatusCode = StatusCodes.Status200OK; _context.Response.ContentType = "application/json"; var serializedEnvelope = _envelopeSerializer.Serialize(envelope); var buffer = ArrayPool <byte> .Shared.Rent(Encoding.UTF8.GetByteCount(serializedEnvelope)); try { var length = Encoding.UTF8.GetBytes(serializedEnvelope, 0, serializedEnvelope.Length, buffer, 0); await _context.Response.Body.WriteAsync(buffer, 0, length, cancellationToken).ConfigureAwait(false); } finally { ArrayPool <byte> .Shared.Return(buffer); } } finally { _sendSemaphore.Release(); } }
private Lazy <string> CreateLazySerializedMessage(IEnvelopeSerializer envelopeSerializer) => new Lazy <string>(() => { if (Message != null) { return(envelopeSerializer.Serialize(Message)); } return(null); });
public Envelope Send(Envelope envelope, Uri address, IEnvelopeSerializer serializer, IMessageCallback callback = null) { ITransport transport = null; if (_transports.TryGetValue(address.Scheme, out transport)) { var sending = envelope.Clone(); var channel = TryGetChannel(address); // TODO -- look up channel node modifiers if any // TODO -- there's a little opportunity here to try to reuse the serialization // if you send to more than one channel at a time w/ the same serializer if (sending.Data == null || sending.Data.Length == 0) { serializer.Serialize(sending, channel); } sending.AcceptedContentTypes = AcceptedContentTypes.ToArray(); if (channel != null) { sending.Destination = channel.Destination; sending.ReplyUri = channel.ReplyUri; if (callback == null) { channel.Sender.Send(sending.Data, sending.Headers); } else { callback.Send(sending); } } else { sending.Destination = address; sending.ReplyUri = transport.DefaultReplyUri(); if (callback == null) { transport.Send(sending.Destination, sending.Data, sending.Headers); } else { callback.Send(sending); } } return(sending); } else { throw new InvalidOperationException($"Unrecognized transport scheme '{address.Scheme}'"); } }
public LazyInput( Message message, Identity userIdentity, BuilderConfiguration builderConfiguration, IDocumentSerializer documentSerializer, IEnvelopeSerializer envelopeSerializer, IArtificialIntelligenceExtension artificialIntelligenceExtension, CancellationToken cancellationToken) { Message = message ?? throw new ArgumentNullException(nameof(message)); _builderConfiguration = builderConfiguration ?? throw new ArgumentNullException(nameof(builderConfiguration)); _lazySerializedContent = new Lazy <string>(() => documentSerializer.Serialize(Content)); _analyzable = new Lazy <bool>(() => { string result = null; Message?.Metadata?.TryGetValue("builder.analyzable", out result); return(result?.ToLower() == "true"); }); _lazyAnalyzedContent = new Lazy <Task <AnalysisResponse> >(async() => { // Only analyze the input if the type is plain text or analyzable metadata is true. if (!_analyzable.Value && Content.GetMediaType() != PlainText.MediaType) { return(null); } try { return(await artificialIntelligenceExtension.AnalyzeAsync( new AnalysisRequest { Text = _lazySerializedContent.Value, Extras = new Dictionary <string, string> { ["MessageId"] = Message.Id, ["UserIdentity"] = userIdentity.ToString() } }, cancellationToken)); } catch (LimeException) { return(null); } }); _lazySerializedMessage = new Lazy <string>(() => { if (Message != null) { return(envelopeSerializer.Serialize(Message)); } return(null); }); }
private async Task <string> RequestAsync(string endpoint, Envelope request, CancellationToken cancellationToken) { using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, $"{MsgingBaseUri}{endpoint}")) { httpRequestMessage.Content = new StringContent(_envelopeSerializer.Serialize(request), Encoding.UTF8, "application/json"); using (var httpResponseMessage = await _httpClient.SendAsync(httpRequestMessage, cancellationToken).ConfigureAwait(false)) { httpResponseMessage.EnsureSuccessStatusCode(); return(await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false)); } } }
/// <summary> /// Sends an envelope to the connected node. /// </summary> /// <param name="envelope">Envelope to be transported</param> /// <param name="cancellationToken"></param> /// <returns></returns> public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (_stream == null) { throw new InvalidOperationException("The stream was not initialized. Call OpenAsync first."); } if (!_stream.CanWrite) { throw new InvalidOperationException("Invalid stream state"); } var serializedEnvelope = _envelopeSerializer.Serialize(envelope); int envelopeByteCount = Encoding.UTF8.GetByteCount(serializedEnvelope); if (envelopeByteCount > _maxSenderBufferSize) { // Prevent sending an envelope that could potentially make the receiver side drop the connection, // since most probably it's _maxBufferSize has the same value used by the sender side await TraceAsync($"EnvelopeTooLarge (size of {envelopeByteCount}): {serializedEnvelope}", DataOperation.Error).ConfigureAwait(false); throw new EnvelopeTooLargeException( $"Envelope NOT sent: {envelope.GetType().Name} with id {envelope.Id} and size {envelopeByteCount} will probably exceed the maximum size supported by a receiver (the local value is {_maxSenderBufferSize})", envelope); } await TraceAsync(serializedEnvelope, DataOperation.Send).ConfigureAwait(false); var buffer = _arrayPool.Rent(envelopeByteCount); var length = Encoding.UTF8.GetBytes(serializedEnvelope, 0, serializedEnvelope.Length, buffer, 0); try { await _stream.WriteAsync(buffer, 0, length, cancellationToken).ConfigureAwait(false); } catch (IOException) { await CloseWithTimeoutAsync().ConfigureAwait(false); throw; } finally { _arrayPool.Return(buffer); } }
public static string ExecuteSerialization(IEnvelopeSerializer serializer, Envelope envelope, int count) { string json = null; var sw = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < count; i++) { json = serializer.Serialize(envelope); } sw.Stop(); System.Console.WriteLine("{0}: {1} ms", serializer.GetType().Name, sw.ElapsedMilliseconds); return json; }
public static string ExecuteSerialization(IEnvelopeSerializer serializer, Envelope envelope, int count) { string json = null; var sw = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < count; i++) { json = serializer.Serialize(envelope); } sw.Stop(); System.Console.WriteLine("{0}: {1} ms", serializer.GetType().Name, sw.ElapsedMilliseconds); return(json); }
public Envelope EnvelopeForSending(Envelope envelope, IEnvelopeSerializer serializer, Uri replyUri) { var clone = envelope.Clone(); // Must be done in this order! Modifiers.Each(x => x.Modify(clone)); serializer.Serialize(clone, this); clone.Headers[Envelope.DestinationKey] = Uri.ToString(); clone.Headers[Envelope.ChannelKey] = Key; if (replyUri != null) { clone.Headers[Envelope.ReplyUriKey] = replyUri.ToString(); } return(clone); }
public LazyInput( Document content, IDictionary <string, string> flowConfiguration, IDocumentSerializer documentSerializer, IEnvelopeSerializer envelopeSerializer, IArtificialIntelligenceExtension artificialIntelligenceExtension, CancellationToken cancellationToken) { _flowConfiguration = flowConfiguration; Content = content; _lazySerializedContent = new Lazy <string>(() => documentSerializer.Serialize(content)); _lazyAnalyzedContent = new Lazy <Task <AnalysisResponse> >(async() => { // Only analyze the input if the type is plain text. if (Content.GetMediaType() != PlainText.MediaType) { return(null); } try { return(await artificialIntelligenceExtension.AnalyzeAsync( new AnalysisRequest { Text = _lazySerializedContent.Value }, cancellationToken)); } catch (LimeException) { return(null); } }); _lazySerializedMessage = new Lazy <string>(() => { var message = EnvelopeReceiverContext <Message> .Envelope; if (message != null) { return(envelopeSerializer.Serialize(message)); } return(null); }); }
public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (WebSocket.State != WebSocketState.Open) { throw new InvalidOperationException("Could not send envelope: websocket is not open"); } var envelopeJson = _envelopeSerializer.Serialize(envelope); if (_traceWriter != null && _traceWriter.IsEnabled) { await _traceWriter.TraceAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); } var jsonBytes = Encoding.UTF8.GetBytes(envelopeJson); await _sendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); if (WebSocket.State != WebSocketState.Open) { throw new InvalidOperationException("Could not send envelope: websocket is not open"); } try { await WebSocket.SendAsync(new ArraySegment <byte>(jsonBytes), _webSocketMessageType, true, cancellationToken).ConfigureAwait(false); } catch (WebSocketException) { await CloseWithTimeoutAsync().ConfigureAwait(false); throw; } finally { _sendSemaphore.Release(); } }
public LazyInput( Message message, BuilderConfiguration builderConfiguration, IDocumentSerializer documentSerializer, IEnvelopeSerializer envelopeSerializer, IArtificialIntelligenceExtension artificialIntelligenceExtension, CancellationToken cancellationToken) { Message = message ?? throw new ArgumentNullException(nameof(message)); _builderConfiguration = builderConfiguration ?? throw new ArgumentNullException(nameof(builderConfiguration)); _lazySerializedContent = new Lazy <string>(() => documentSerializer.Serialize(Content)); _lazyAnalyzedContent = new Lazy <Task <AnalysisResponse> >(async() => { // Only analyze the input if the type is plain text. if (Content.GetMediaType() != PlainText.MediaType) { return(null); } try { return(await artificialIntelligenceExtension.AnalyzeAsync( new AnalysisRequest { Text = _lazySerializedContent.Value }, cancellationToken)); } catch (LimeException) { return(null); } }); _lazySerializedMessage = new Lazy <string>(() => { if (Message != null) { return(envelopeSerializer.Serialize(Message)); } return(null); }); }
/// <summary> /// Writes a envelope into the send pipe. /// </summary> public async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (_sendTask == null) { throw new InvalidOperationException($"The send task was not initialized. Call {nameof(StartAsync)} first."); } if (_sendTask.IsCompleted) { throw new InvalidOperationException("Send task is completed"); } var envelopeJson = _envelopeSerializer.Serialize(envelope); await TraceAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); // Gets memory from the pipe to write the encoded string. // .NET string are UTF16 and the length to UTF8 is usually larger. // We can use Encoding.UTF8.GetBytes instead to get the precise length but here this is just a hint and the impact is irrelevant, // so we can avoid the overhead. var memory = _sendPipe.Writer.GetMemory(envelopeJson.Length); var length = Encoding.UTF8.GetBytes(envelopeJson, memory.Span); if (_pauseWriterThreshold > 0 && length >= _pauseWriterThreshold) { throw new InvalidOperationException("Serialized envelope size is larger than pauseWriterThreshold and cannot be sent"); } // Signals the pipe that the data is ready. _sendPipe.Writer.Advance(length); var flushResult = await _sendPipe.Writer.FlushAsync(cancellationToken).ConfigureAwait(false); if (flushResult.IsCompleted || flushResult.IsCanceled) { throw new InvalidOperationException("Send pipe is completed"); } }
public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { var session = envelope as Session; if (session != null && session.State <= SessionState.Established) { await UpdateReceiveChannelNameAsync(session, cancellationToken); } var envelopeJson = _envelopeSerializer.Serialize(envelope); await _traceWriter.TraceIfEnabledAsync(envelopeJson, DataOperation.Send); // Send to the channel or to the server prefix await _connectionMultiplexer .GetSubscriber() .PublishAsync(_sendChannelName ?? GetListenerChannelName(_channelNamespace, ServerChannelPrefix), envelopeJson) .ConfigureAwait(false); }
private async Task <Command> RunCommandAsync(Command command) { var commandString = _envelopeSerializer.Serialize(command); using (var httpContent = new StringContent(commandString, Encoding.UTF8, "application/json")) { try { var response = await _client.PostAsync("/commands", httpContent); response.EnsureSuccessStatusCode(); var responseBody = await response.Content.ReadAsStringAsync(); return((Command)_envelopeSerializer.Deserialize(responseBody)); } catch (Exception ex) { _logger.LogError(ex, "Failed to run command"); throw ex; } } }
/// <summary> /// Sends an envelope to the connected node. /// </summary> /// <param name="envelope">Envelope to be transported</param> /// <param name="cancellationToken"></param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (_stream == null) { throw new InvalidOperationException("The stream was not initialized. Call OpenAsync first."); } if (!_stream.CanWrite) { throw new InvalidOperationException("Invalid stream state"); } var envelopeJson = _envelopeSerializer.Serialize(envelope); await TraceAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); var jsonBytes = Encoding.UTF8.GetBytes(envelopeJson); await _sendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { await _stream.WriteAsync(jsonBytes, 0, jsonBytes.Length, cancellationToken).ConfigureAwait(false); } catch (IOException) { await CloseWithTimeoutAsync().ConfigureAwait(false); throw; } finally { _sendSemaphore.Release(); } }
/// <summary> /// Sends an envelope to the connected node. /// </summary> /// <param name="envelope">Envelope to be transported</param> /// <param name="cancellationToken"></param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (_stream == null) { throw new InvalidOperationException("The stream was not initialized. Call OpenAsync first."); } if (!_stream.CanWrite) { throw new InvalidOperationException("Invalid stream state"); } var serializedEnvelope = _envelopeSerializer.Serialize(envelope); await TraceAsync(serializedEnvelope, DataOperation.Send).ConfigureAwait(false); var buffer = _arrayPool.Rent(Encoding.UTF8.GetByteCount(serializedEnvelope)); var length = Encoding.UTF8.GetBytes(serializedEnvelope, 0, serializedEnvelope.Length, buffer, 0); try { await _stream.WriteAsync(buffer, 0, length, cancellationToken).ConfigureAwait(false); } catch (IOException) { await CloseWithTimeoutAsync().ConfigureAwait(false); throw; } finally { _arrayPool.Return(buffer); } }
public override async Task SendAsync(Envelope envelope, CancellationToken cancellationToken) { EnsureIsConnected(); await _sendSemaphore.WaitAsync(cancellationToken); try { using (var stream = _webSocket.CreateMessageWriter(WebSocketMessageType.Text)) { using (var writer = new StreamWriter(stream, Encoding.UTF8)) { var envelopeJson = _envelopeSerializer.Serialize(envelope); await TraceDataIfEnabledAsync(envelopeJson, DataOperation.Send).ConfigureAwait(false); await writer.WriteAsync(envelopeJson).ConfigureAwait(false); } } } finally { _sendSemaphore.Release(); } }
private HttpContent GetContent(Envelope envelope) => new StringContent(_serializer.Serialize(envelope), Encoding.UTF8, "application/json");
public Envelope EnvelopeForSending(Envelope envelope, IEnvelopeSerializer serializer, Uri replyUri) { var clone = envelope.Clone(); // Must be done in this order! Modifiers.Each(x => x.Modify(clone)); serializer.Serialize(clone, this); clone.Headers[Envelope.DestinationKey] = Uri.ToString(); clone.Headers[Envelope.ChannelKey] = Key; if (replyUri != null) { clone.Headers[Envelope.ReplyUriKey] = replyUri.ToString(); } return clone; }