示例#1
0
 public WrapperStreamObserver(IStreamObserver <TK, TP> o, OwnedThreadsScheduler scheduler, Guid classId, TaskEntry t)
 {
     this.o         = o;
     this.scheduler = scheduler;
     this.classId   = classId;
     this.te        = t;
 }
示例#2
0
        public IStreamObserver <TK, TP> RegisterStreamObserver <TK, TP>(IStreamObserver <TK, TP> o, Guid?classId = null)
        {
            // Check if already wrapped
            if (o as WrapperStreamObserver <TK, TP> != null)
            {
                return(o);
            }

            var cid = o.ClassId;

            if (this.useCommonSprayPool && (classId != null))
            {
                cid = classId.Value;
            }

            var t = new TaskEntry(cid, m => o.OnNext((StreamMessage <TK, TP>)m), o.OnCompleted, o.OnFlush, o.OnError);

            this.taskTable.TryAdd(cid, t);

            return(new WrapperStreamObserver <TK, TP>(o, this, t));
        }
示例#3
0
        public void Run(object obj)
        {
            int id = (int)obj;

            if (this.scheduler.affinitize)
            {
                NativeMethods.AffinitizeThread(id);
            }

            TaskEntry te = null;

            while (!this.stopped)
            {
                lock (this.scheduler.global)
                {
                    if (te != null)
                    {
                        if (te.TaskCount > 0)
                        {
                            // Add operator back to pending list with corrected priority
                            te.Status = TaskEntryStatus.HasWork;
                            this.scheduler.pendingTasks.Add(te);
                        }
                        else
                        {
                            te.Status = TaskEntryStatus.Inactive;
                        }
                    }

                    te = null;
                    while (!this.stopped && (this.scheduler.pendingTasks.Count == 0))
                    {
                        Monitor.Wait(this.scheduler.global);
                    }

                    if (this.stopped)
                    {
                        return;
                    }

                    this.scheduler.pendingTasks.TryGetFirst(out te);
                    this.scheduler.pendingTasks.Remove(te);
                    te.Status = TaskEntryStatus.Processing;

                    if (this.scheduler.pendingTasks.Count > 0)
                    {
                        Monitor.Pulse(this.scheduler.global);
                    }
                }

                try
                {
                    long now = -1;
                    long mt  = -1;
                    int  par = 0;
                    while (te.tasks.TryPeek(out var message))
                    {
                        mt = message.Kind == MessageKind.DataBatch ? message.Message.MinTimestamp : StreamEvent.InfinitySyncTime;
                        if ((now == -1) || (now == mt))
                        {
                            now = mt;
                            if (!te.tasks.TryDequeue(out message))
                            {
                                throw new InvalidOperationException("Could not dequeue task from task entry");
                            }

                            var newCount = Interlocked.Decrement(ref te.TaskCount);

                            switch (message.Kind)
                            {
                            case MessageKind.DataBatch:
                                if (te.Disposed)
                                {
                                    message.Message.Free();
                                }
                                else
                                {
                                    te.onNext(message.Message);
                                }
                                break;

                            case MessageKind.Completed:
                                if (!te.Completed)
                                {
                                    te.OnCompleted();
                                    this.scheduler.taskTable.TryRemove(te.ClassId, out var tmp);
                                }
                                break;

                            case MessageKind.Flush:
                                te.onFlush();
                                break;
                            }

                            par++;
                            if (newCount == 0)
                            {
                                break;
                            }
                        }
                        else
                        {
                            te.Priority = mt;
                            if (this.scheduler.pendingTasks.Count > 0)
                            {
                                break;
                            }
                            now = mt;
                        }
                    }
                }
                catch (Exception e)
                {
                    te.onError(e);
                }
            }
        }