private void SendToWebSockets(LogMessageEntry item, ArraySegment <byte> bytes) { if (_tasks.Length != item.WebSocketsList.Count) { Array.Resize(ref _tasks, item.WebSocketsList.Count); } for (int i = 0; i < item.WebSocketsList.Count; i++) { var socket = item.WebSocketsList[i]; try { _tasks[i] = socket.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception e) { RemoveWebSocket(socket, e.ToString()); } } try { if (Task.WaitAll(_tasks, 250)) { return; } } catch { // ignored } for (int i = 0; i < _tasks.Length; i++) { var task = _tasks[i]; string error = null; if (task.IsFaulted) { error = task.Exception?.ToString() ?? "Faulted"; } else if (task.IsCanceled) { error = "Canceled"; } else if (task.IsCompleted == false) { error = "Timeout - 250 milliseconds"; } if (error != null) { RemoveWebSocket(item.WebSocketsList[i], error); } } }
private int ActualWriteToLogTargets(LogMessageEntry item, Stream file) { item.Data.TryGetBuffer(out var bytes); Debug.Assert(bytes.Array != null); if (item.Type == LogMode.Operations && LogMode != LogMode.None || (LogMode & LogMode.Information) == LogMode.Information) { file.Write(bytes.Array, bytes.Offset, bytes.Count); _additionalOutput?.Write(bytes.Array, bytes.Offset, bytes.Count); if (item.Task != null) { try { file.Flush(); _additionalOutput?.Flush(); } finally { item.Task.TrySetResult(null); } } } else { item.Task?.TrySetResult(null); } try { _pipeSink?.Write(bytes.Array, bytes.Offset, bytes.Count); } catch { // broken pipe } if (!_listeners.IsEmpty) { // this is rare SendToWebSockets(item, bytes); } item.Data.SetLength(0); item.WebSocketsList.Clear(); return(bytes.Count); }
public void Log(ref LogEntry entry, TaskCompletionSource <object> tcs = null) { var state = _localState.Value; if (state.Generation != _generation) { state = _localState.Value = GenerateThreadWriterState(); } int currentProcessNumber = CurrentProcessorIdHelper.GetCurrentProcessorId() % _freePooledMessageEntries.Length; var pool = _freePooledMessageEntries[currentProcessNumber]; if (pool.TryDequeue(out var item)) { item.Data.SetLength(0); item.WebSocketsList.Clear(); item.Task = tcs; state.ForwardingStream.Destination = item.Data; } else { item = new LogMessageEntry { Task = tcs }; state.ForwardingStream.Destination = new MemoryStream(); } foreach (var kvp in _listeners) { if (kvp.Value.Filter.Forward(ref entry)) { item.WebSocketsList.Add(kvp.Key); } } WriteEntryToWriter(state.Writer, ref entry); item.Data = state.ForwardingStream.Destination; Debug.Assert(item.Data != null); item.Type = entry.Type; _activePoolMessageEntries[currentProcessNumber].Enqueue(item, 128); _hasEntries.Set(); }
private void SendToWebSockets(LogMessageEntry item, ArraySegment <byte> bytes) { if (_tasks.Length != item.WebSocketsList.Count) { Array.Resize(ref _tasks, item.WebSocketsList.Count); } for (int i = 0; i < item.WebSocketsList.Count; i++) { var socket = item.WebSocketsList[i]; try { _tasks[i] = socket.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception) { RemoveWebSocket(socket); } } bool success; try { success = Task.WaitAll(_tasks, 250); } catch (Exception) { success = false; } if (success == false) { for (int i = 0; i < _tasks.Length; i++) { if (_tasks[i].IsFaulted || _tasks[i].IsCanceled || _tasks[i].IsCompleted == false) { // this either timed out or errored, removing it. RemoveWebSocket(item.WebSocketsList[i]); } } } }