コード例 #1
0
        public override Task <(long commitLogPosition, long inputQueuePosition)> RecoverAsync()
        {
            foreach (var guid in this.ReadCheckpointIntentions())
            {
                this.failedCheckpoints.Add(guid);
            }

            var tasks = new List <Task>();

            // kick off loads for all singletons
            foreach (var key in TrackedObjectKey.GetSingletons())
            {
                var loadTask = this.LoadAsync(key);
                this.pendingLoads.Add(key, new PendingLoad()
                {
                    EffectTracker = null,
                    ReadEvents    = new List <PartitionReadEvent>(),
                    LoadTask      = loadTask,
                });
                tasks.Add(loadTask);
            }

            Task.WhenAll(tasks).GetAwaiter().GetResult();

            this.CompletePending();

            var dedupState = (DedupState)this.cache[TrackedObjectKey.Dedup].TrackedObject;

            return(Task.FromResult(dedupState.Positions));
        }
コード例 #2
0
            public void InitialUpdater(ref Key key, ref EffectTracker tracker, ref Value value)
            {
                var trackedObject = TrackedObjectKey.Factory(key.Val);

                this.stats.Create++;
                trackedObject.Partition = this.partition;
                value.Val = trackedObject;
                tracker.ProcessEffectOn(trackedObject);
                this.stats.Modify++;
            }
コード例 #3
0
 // create a tracked object on the main session (only one of these is executing at a time)
 public override ValueTask <TrackedObject> CreateAsync(Key key)
 {
     try
     {
         TrackedObject newObject = TrackedObjectKey.Factory(key);
         newObject.Partition = this.partition;
         Value newValue = newObject;
         // Note: there is no UpsertAsync().
         this.mainSession.Upsert(ref key, ref newValue);
         return(new ValueTask <TrackedObject>(newObject));
     }
     catch (Exception exception)
         when(this.terminationToken.IsCancellationRequested && !Utils.IsFatal(exception))
         {
             throw new OperationCanceledException("Partition was terminated.", exception, this.terminationToken);
         }
 }
コード例 #4
0
        IAsyncEnumerable <OrchestrationState> ScanOrchestrationStates(
            EffectTracker effectTracker,
            PartitionQueryEvent queryEvent)
        {
            var    instanceQuery = queryEvent.InstanceQuery;
            string queryId       = queryEvent.EventIdString;

            this.partition.EventDetailTracer?.TraceEventProcessingDetail($"starting query {queryId}");

            // we use a separate thread to iterate, since Faster can iterate synchronously only at the moment
            // and we don't want it to block thread pool worker threads
            var channel    = Channel.CreateBounded <OrchestrationState>(500);
            var scanThread = new Thread(RunScan)
            {
                Name = $"QueryScan-{queryId}"
            };

            scanThread.Start();
            return(channel.Reader.ReadAllAsync());

            void RunScan()
            {
                using var _ = EventTraceContext.MakeContext(0, queryId);

                // get the unique set of keys appearing in the log and emit them
                using var iter1 = this.fht.Iterate();

                Stopwatch stopwatch = new Stopwatch();

                stopwatch.Start();
                long scanned      = 0;
                long deserialized = 0;
                long matched      = 0;
                long lastReport;

                void ReportProgress()
                {
                    this.partition.EventDetailTracer?.TraceEventProcessingDetail(
                        $"query {queryId} scan position={iter1.CurrentAddress} elapsed={stopwatch.Elapsed.TotalSeconds:F2}s scanned={scanned} deserialized={deserialized} matched={matched}");
                    lastReport = stopwatch.ElapsedMilliseconds;
                }

                ReportProgress();

                while (iter1.GetNext(out RecordInfo recordInfo) && !recordInfo.Tombstone)
                {
                    if (stopwatch.ElapsedMilliseconds - lastReport > 5000)
                    {
                        ReportProgress();
                    }

                    TrackedObjectKey key = iter1.GetKey().Val;
                    if (key.ObjectType == TrackedObjectKey.TrackedObjectType.Instance)
                    {
                        scanned++;
                        //this.partition.EventDetailTracer?.TraceEventProcessingDetail($"found instance {key.InstanceId}");

                        if (string.IsNullOrEmpty(instanceQuery?.InstanceIdPrefix) ||
                            key.InstanceId.StartsWith(instanceQuery.InstanceIdPrefix))
                        {
                            //this.partition.EventDetailTracer?.TraceEventProcessingDetail($"reading instance {key.InstanceId}");

                            object val = iter1.GetValue().Val;

                            //this.partition.EventDetailTracer?.TraceEventProcessingDetail($"read instance {key.InstanceId}, is {(val == null ? "null" : val.GetType().Name)}");

                            InstanceState instanceState;

                            if (val is byte[] bytes)
                            {
                                instanceState = (InstanceState)Serializer.DeserializeTrackedObject(bytes);
                                deserialized++;
                            }
                            else
                            {
                                instanceState = (InstanceState)val;
                            }

                            // reading the orchestrationState may race with updating the orchestration state
                            // but it is benign because the OrchestrationState object is immutable
                            var orchestrationState = instanceState?.OrchestrationState;

                            if (orchestrationState != null &&
                                instanceQuery.Matches(orchestrationState))
                            {
                                matched++;

                                this.partition.EventDetailTracer?.TraceEventProcessingDetail($"match instance {key.InstanceId}");

                                var value = orchestrationState.ClearFieldsImmutably(!instanceQuery.FetchInput, false);

                                var task = channel.Writer.WriteAsync(value);

                                if (!task.IsCompleted)
                                {
                                    task.AsTask().Wait();
                                }
                            }
                        }
                    }
                }

                ReportProgress();

                channel.Writer.Complete();

                this.partition.EventDetailTracer?.TraceEventProcessingDetail($"finished query {queryId}");
            }
        }