Example #1
0
        public Watcher(StreamReader streamReader, Action <WatchEventType, T> onEvent, Action <Exception> onError)
        {
            _streamReader = streamReader;
            OnEvent      += onEvent;
            OnError      += onError;

            _cts = new CancellationTokenSource();

            var token = _cts.Token;

            Task.Run(async() =>
            {
                try
                {
                    Watching = true;

                    while (!streamReader.EndOfStream)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        var line = await streamReader.ReadLineAsync();

                        try
                        {
                            var genericEvent = SafeJsonConvert.DeserializeObject <k8s.Watcher <KubernetesObject> .WatchEvent>(line);

                            if (genericEvent.Object.Kind == "Status")
                            {
                                var statusEvent = SafeJsonConvert.DeserializeObject <k8s.Watcher <V1Status> .WatchEvent>(line);
                                var exception   = new KubernetesException(statusEvent.Object);
                                this.OnError?.Invoke(exception);
                            }
                            else
                            {
                                var @event = SafeJsonConvert.DeserializeObject <k8s.Watcher <T> .WatchEvent>(line);
                                this.OnEvent?.Invoke(@event.Type, @event.Object);
                            }
                        }
                        catch (Exception e)
                        {
                            // error if deserialized failed or onevent throws
                            OnError?.Invoke(e);
                        }
                    }
                }
                catch (Exception e)
                {
                    // error when transport error, IOException ect
                    OnError?.Invoke(e);
                }
                finally
                {
                    Watching = false;
                }
            }, token);
        }
Example #2
0
        internal static async IAsyncEnumerable <(WatchEventType, T)> CreateWatchEventEnumerator(
            Func <Task <TextReader> > streamReaderCreator,
            Action <Exception> onError = null,
            [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            Task <TR> AttachCancellationToken <TR>(Task <TR> task)
            {
                if (!task.IsCompleted)
                {
                    // here to pass cancellationToken into task
                    return(task.ContinueWith(t => t.GetAwaiter().GetResult(), cancellationToken));
                }

                return(task);
            }

            using var streamReader = await AttachCancellationToken(streamReaderCreator ()).ConfigureAwait(false);

            for (; ;)
            {
                // ReadLineAsync will return null when we've reached the end of the stream.
                var line = await AttachCancellationToken(streamReader.ReadLineAsync()).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();

                if (line == null)
                {
                    yield break;
                }

                WatchEvent @event = null;

                try
                {
                    var genericEvent = KubernetesJson.Deserialize <Watcher <KubernetesObject> .WatchEvent>(line);

                    if (genericEvent.Object.Kind == "Status")
                    {
                        var statusEvent = KubernetesJson.Deserialize <Watcher <V1Status> .WatchEvent>(line);
                        var exception   = new KubernetesException(statusEvent.Object);
                        onError?.Invoke(exception);
                    }
                    else
                    {
                        @event = KubernetesJson.Deserialize <WatchEvent>(line);
                    }
                }
                catch (Exception e)
                {
                    onError?.Invoke(e);
                }


                if (@event != null)
                {
                    yield return(@event.Type, @event.Object);
                }
            }
        }
        private async Task WatcherLoop(CancellationToken cancellationToken)
        {
            // Make sure we run async
            await Task.Yield();

            try
            {
                Watching = true;
                string line;
                _streamReader = await _streamReaderCreator();

                // ReadLineAsync will return null when we've reached the end of the stream.
                while ((line = await _streamReader.ReadLineAsync().ConfigureAwait(false)) != null)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    try
                    {
                        var genericEvent = SafeJsonConvert.DeserializeObject <k8s.Watcher <KubernetesObject> .WatchEvent>(line);

                        if (genericEvent.Object.Kind == "Status")
                        {
                            var statusEvent = SafeJsonConvert.DeserializeObject <k8s.Watcher <V1Status> .WatchEvent>(line);
                            var exception   = new KubernetesException(statusEvent.Object);
                            this.OnError?.Invoke(exception);
                        }
                        else
                        {
                            var @event = SafeJsonConvert.DeserializeObject <k8s.Watcher <T> .WatchEvent>(line);
                            this.OnEvent?.Invoke(@event.Type, @event.Object);
                        }
                    }
                    catch (Exception e)
                    {
                        // error if deserialized failed or onevent throws
                        OnError?.Invoke(e);
                    }
                }
            }
            catch (Exception e)
            {
                // error when transport error, IOException ect
                OnError?.Invoke(e);
            }
            finally
            {
                Watching = false;
                OnClosed?.Invoke();
            }
        }