Ejemplo n.º 1
0
        public async Task <IActionResult> Post([FromBody] RateRequest request)
        {
            try
            {
                //TODO: Do some snaity checking on the request model
                ServiceEventSource.Current.ServiceMessage(
                    this.context,
                    "Received request for hotel",
                    request.HotelName);

                IReliableQueue <RateRequest> queue = await this.stateManager.GetOrAddAsync <IReliableQueue <RateRequest> >(RatesService.RateQueueName);

                using (ITransaction tx = this.stateManager.CreateTransaction())
                {
                    // Queue the request
                    await queue.EnqueueAsync(tx, request);

                    // Commit
                    await tx.CommitAsync();
                }

                return(Ok());
            }
            catch (Exception e)
            {
                return(BadRequest(e.Message));
            }
        }
        private async Task AddBufferedWorkItemAsync(Wi workItem)
        {
            if (this.m_NumOfBufferedWorkItems >= this.m_MaxNumOfBufferedWorkItems)
            {
                throw new InvalidOperationException(string.Format("Work Manger is at maximum buffered work items:{0}", this.m_NumOfBufferedWorkItems));
            }


            try
            {
                // Which Q
                IReliableQueue <Wi> targetQueue = await this.m_QueueManager.GetOrAddQueueAsync(workItem.QueueName);

                // enqueue
                using (ITransaction tx = this.StateManager.CreateTransaction())
                {
                    await targetQueue.EnqueueAsync(tx, workItem, TimeSpan.FromSeconds(10), CancellationToken.None);

                    await tx.CommitAsync();
                }
                this.IncreaseBufferedWorkItems();
                this.m_DeferedTaskExec.AddWork(this.TryIncreaseExecuters);
            }
            catch (AggregateException aex)
            {
                AggregateException ae = aex.Flatten();

                this.m_TraceWriter.TraceMessage(
                    string.Format(
                        "Post to work manager failed, caller should retry E:{0} StackTrace:{1}",
                        ae.GetCombinedExceptionMessage(),
                        ae.GetCombinedExceptionStackTrace()));
                throw;
            }
        }
Ejemplo n.º 3
0
        internal async Task <bool> TryDequeueAndProcessAsync(CancellationToken cancellationToken)
        {
            IReliableQueue <Guid> queue =
                await this.StateManager.GetOrAddAsync <IReliableQueue <Guid> >(QueueName);

            IReliableDictionary <Guid, ApplicationDeployment> dictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, ApplicationDeployment> >(DictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <Guid> workItem = await queue.TryDequeueAsync(tx, this.transactionTimeout, cancellationToken);

                if (!workItem.HasValue)
                {
                    ServiceEventSource.Current.ServiceMessage(this, "No new application deployment requests.");
                    return(false);
                }

                Guid workItemId = workItem.Value;

                ConditionalValue <ApplicationDeployment> appDeployment =
                    await dictionary.TryGetValueAsync(tx, workItemId, LockMode.Update, this.transactionTimeout, cancellationToken);

                if (!appDeployment.HasValue)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "Found queued application deployment request with no associated deployment information. Discarding.");

                    return(true);
                }

                ApplicationDeployment processedDeployment = await this.ProcessApplicationDeployment(appDeployment.Value, cancellationToken);

                if (processedDeployment.Status == ApplicationDeployStatus.Complete ||
                    processedDeployment.Status == ApplicationDeployStatus.Failed)
                {
                    // Remove deployments that completed or failed
                    await dictionary.TryRemoveAsync(tx, workItemId, this.transactionTimeout, cancellationToken);
                }
                else
                {
                    // The deployment hasn't completed or failed, so queue up the next stage of deployment
                    await queue.EnqueueAsync(tx, workItemId, this.transactionTimeout, cancellationToken);

                    // And update the deployment record with the new status
                    await dictionary.SetAsync(tx, workItemId, processedDeployment, this.transactionTimeout, cancellationToken);

                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "Application deployment request successfully processed. Cluster: {0}. Status: {1}",
                        processedDeployment.Cluster,
                        processedDeployment.Status);
                }

                await tx.CommitAsync();
            }

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This is the main entry point for your service replica.
        /// This method executes when this replica of your service becomes primary and has write status.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service replica.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            // TODO: Replace the following sample code with your own logic
            //       or remove this RunAsync override if it's not needed in your service.

            IReliableQueue <string> reliableQueue = await StateManager.GetOrAddAsync <IReliableQueue <string> >("Queue1");

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                using (var tx = StateManager.CreateTransaction())
                {
                    //var result = await reliableQueue.TryDequeueAsync(tx);

                    //ServiceEventSource.Current.ServiceMessage(this, "Current Counter Value: {0}", result.HasValue ? result.Value : "Value does not exist.");

                    //if (result.HasValue)
                    //{
                    //    await reliableQueue.EnqueueAsync(tx, result.Value);

                    //}

                    await reliableQueue.EnqueueAsync(tx, DateTimeOffset.Now.ToString());

                    // If an exception is thrown before calling CommitAsync, the transaction aborts, all changes are
                    // discarded, and nothing is saved to the secondary replicas.
                    await tx.CommitAsync();
                }

                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
            }
        }
 public async Task UpdateTask(ITask task)
 {
     if (!m_tx.TryGetValue(task, out var tx))
     {
         return;
     }
     try
     {
         await ServiceFabricUtils.DoWithTimeoutRetry(
             async() => await m_queue.EnqueueAsync(tx, Utils.Serialize(task), TimeSpan.FromSeconds(10), m_cancel),
             async() => await tx.CommitAsync());
     }
     finally
     {
         ReleaseTx(task, tx);
     }
 }
        public async Task GetInLineAsync(string appApiLicenseCode, Guid consumerActorId)
        {
            IReliableQueue <Guid> queue = await StateManager.GetOrAddAsync <IReliableQueue <Guid> >(appApiLicenseCode).ConfigureAwait(false);

            using (ITransaction tx = StateManager.CreateTransaction())
            {
                await queue.EnqueueAsync(tx, consumerActorId).ConfigureAwait(false);

                await tx.CommitAsync();
            }
        }
        public async Task <IHttpActionResult> AddWord(string word)
        {
            IReliableQueue <string> queue = await this.stateManager.GetOrAddAsync <IReliableQueue <string> >("inputQueue");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await queue.EnqueueAsync(tx, word);

                await tx.CommitAsync();
            }

            return(this.Ok());
        }
        /// <summary>
        /// This method uses an IReliableQueue to store completed RestockRequests which are later sent to the client using batch processing.
        /// We could send the request immediately but we prefer to minimize traffic back to the Inventory Service by batching multiple requests
        /// in one trip.
        /// </summary>
        /// <param name="actorId"></param>
        /// <param name="request"></param>
        public async void RestockRequestCompleted(ActorId actorId, RestockRequest request)
        {
            IReliableQueue <RestockRequest> completedRequests = await this.StateManager.GetOrAddAsync <IReliableQueue <RestockRequest> >(CompletedRequestsQueueName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                await completedRequests.EnqueueAsync(tx, request);

                await tx.CommitAsync();
            }

            IRestockRequestActor restockRequestActor = ActorProxy.Create <IRestockRequestActor>(actorId, this.ApplicationName);
            await restockRequestActor.UnsubscribeAsync <IRestockRequestEvents>(this); //QUESTION:What does this method do?
        }
Ejemplo n.º 9
0
        public async Task ResetAsync()
        {
            IReliableDictionary <string, int> states = await StateManager.GetOrAddAsync <IReliableDictionary <string, int> >("states");

            IReliableQueue <string> events = await StateManager.GetOrAddAsync <IReliableQueue <string> >("events");

            using (ITransaction transaction = StateManager.CreateTransaction())
            {
                await states.SetAsync(transaction, "Counter", 0);

                await events.EnqueueAsync(transaction, $"{DateTime.UtcNow:O} The Counter is reset.");

                await transaction.CommitAsync();
            }
        }
        public async Task PutMessagesAsync(IReadOnlyCollection <QueueMessage> messages, CancellationToken cancellationToken)
        {
            IReliableQueue <byte[]> collection = await _stateManager.GetOrAddAsync <IReliableQueue <byte[]> >(_queueName);

            using (var tx = new ServiceFabricTransaction(_stateManager, null))
            {
                foreach (QueueMessage message in messages)
                {
                    byte[] data = message.ToByteArray();
                    await collection.EnqueueAsync(tx.Tx, data, _timeout, cancellationToken);
                }

                await tx.CommitAsync();
            }
        }
        public async Task <bool> LogPurchase(IdempotentMessage <PurchaseInfo> idempotentMessage)
        {
            if (LogQueue == null)
            {
                return(false);
            }
            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                await LogQueue.EnqueueAsync(tx, idempotentMessage);

                await tx.CommitAsync();

                return(true);
            }
        }
Ejemplo n.º 12
0
        public async Task <string> CountAsync()
        {
            await Task.Delay(TimeSpan.FromSeconds(3));

            IReliableDictionary <string, int> states = await StateManager.GetOrAddAsync <IReliableDictionary <string, int> >("states");

            IReliableQueue <string> events = await StateManager.GetOrAddAsync <IReliableQueue <string> >("events");

            int number;

            //using (ITransaction transaction = StateManager.CreateTransaction())
            //{
            //    ConditionalValue<int> counter = await states.TryGetValueAsync(transaction, "Counter");
            //    number = counter.HasValue ? counter.Value : 0;
            //    number++;
            //}

            //await Task.Delay(TimeSpan.FromSeconds(3));

            //using (ITransaction transaction = StateManager.CreateTransaction())
            //{
            //    await states.SetAsync(transaction, "Counter", number);
            //    await events.EnqueueAsync(transaction, $"{DateTime.UtcNow:O} The Counter is {number}.");

            //    await transaction.CommitAsync();
            //}

            using (ITransaction transaction = StateManager.CreateTransaction())
            {
                ConditionalValue <int> counter = await states.TryGetValueAsync(transaction, "Counter");

                number = counter.HasValue ? counter.Value : 0;
                number++;

                await Task.Delay(TimeSpan.FromSeconds(3));

                await states.SetAsync(transaction, "Counter", number);

                await events.EnqueueAsync(transaction, $"{DateTime.UtcNow:O} The Counter is {number}.");

                await transaction.CommitAsync();
            }

            return($"Current number is {number}, from partition {Context.PartitionId} and replica {Context.ReplicaId}");
        }
        public async Task AddMessageAsync(string roomName, ChatMessage chatMessage, CancellationToken cancellationToken)
        {
            IReliableQueue <ChatMessage> room = await GetRoomQueue(roomName);

            using (var tx = stateManager.CreateTransaction())
            {
                long msgCount = await room.GetCountAsync(tx);

                if (msgCount == 0)
                {
                    // new room, increment counter
                    await IncrementRoomCountAsync(1, cancellationToken, tx);
                }

                await room.EnqueueAsync(tx, chatMessage);

                await tx.CommitAsync();
            }
        }
Ejemplo n.º 14
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            IReliableQueue <string> messageQueue = await this.StateManager.GetOrAddAsync <IReliableQueue <string> >("messageQueue");

            const string baseAddress = "http://localhost:8864";

            using (Microsoft.Owin.Hosting.WebApp.Start <Startup>(baseAddress))
            {
                HttpClient          client = new HttpClient();
                HttpResponseMessage res    = client.GetAsync(baseAddress + "api/values/5").Result;
                res.EnsureSuccessStatusCode();
                var results = res.Content.ReadAsStringAsync().Result;
                using (ITransaction tx = this.StateManager.CreateTransaction())
                {
                    await messageQueue.EnqueueAsync(tx, results);

                    await tx.CommitAsync();
                }
            }
        }
Ejemplo n.º 15
0
        public async Task GetQueueLength()
        {
            MockApplicationLifetime  appLifetime  = new MockApplicationLifetime();
            MockReliableStateManager stateManager = new MockReliableStateManager();

            IReliableQueue <DeviceEventSeries> queue =
                await stateManager.GetOrAddAsync <IReliableQueue <DeviceEventSeries> >(DataService.EventQueueName);

            using (ITransaction tx = stateManager.CreateTransaction())
            {
                await queue.EnqueueAsync(tx, new DeviceEventSeries("", new DeviceEvent[0]));
            }

            DevicesController target = new DevicesController(stateManager, appLifetime);
            IActionResult     result = await target.GetQueueLengthAsync();

            Assert.True(result is OkObjectResult);
            long actual = (long)((OkObjectResult)result).Value;

            Assert.Equal(1, actual);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Queues deployment of application packages to the given cluster.
        /// </summary>
        /// <param name="clusterAddress"></param>
        /// <param name="clusterPort"></param>
        /// <returns></returns>
        public async Task <IEnumerable <Guid> > QueueApplicationDeploymentAsync(string clusterAddress, int clusterPort)
        {
            IReliableQueue <Guid> queue =
                await this.StateManager.GetOrAddAsync <IReliableQueue <Guid> >(QueueName);

            IReliableDictionary <Guid, ApplicationDeployment> dictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, ApplicationDeployment> >(DictionaryName);

            List <Guid> workIds = new List <Guid>(this.ApplicationPackages.Count());

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                // Grab each application package that's included with the service
                // and create an ApplicationDeployment record of it.
                // Then queue a job to begin processing each one.
                foreach (ApplicationPackageInfo package in this.ApplicationPackages)
                {
                    Guid id = Guid.NewGuid();
                    ApplicationDeployment applicationDeployment = new ApplicationDeployment(
                        cluster: GetClusterAddress(clusterAddress, clusterPort),
                        status: ApplicationDeployStatus.Copy,
                        imageStorePath: null,
                        applicationTypeName: package.ApplicationTypeName,
                        applicationTypeVersion: package.ApplicationTypeVersion,
                        applicationInstanceName: GetApplicationInstanceName(package.PackageFileName),
                        packageZipFilePath: Path.Combine(this.applicationPackageDataPath.FullName, package.PackageFileName),
                        timestamp: DateTimeOffset.UtcNow);

                    await dictionary.AddAsync(tx, id, applicationDeployment);

                    await queue.EnqueueAsync(tx, id);

                    workIds.Add(id);
                }

                await tx.CommitAsync();

                return(workIds);
            }
        }
Ejemplo n.º 17
0
        public async Task Post(string name, string parameters)
        {
            IReliableQueue <string> queue = await this.stateManager.GetOrAddAsync <IReliableQueue <string> >("jobQueue");

            IReliableDictionary <string, Job> dictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, Job> >("jobs");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                if (await dictionary.ContainsKeyAsync(tx, name, LockMode.Update))
                {
                    throw new ArgumentException($"Job {name} already exists.");
                }

                Job job = new Job(name, parameters, false);

                await queue.EnqueueAsync(tx, name);

                await dictionary.SetAsync(tx, name, job);

                await tx.CommitAsync();
            }
        }
Ejemplo n.º 18
0
            private async Task workLoopAsync()
            {
                int nLongDequeueWaitTimeMs  = 20 * 1000;
                int nShortDequeueWaitTimeMs = 2 * 1000;
                int nNoQueueWaitTimeMS      = 5 * 1000;
                int nPauseCheckMs           = 5 * 1000;

                while (this.m_KeepWorking)
                {
                    // pause check
                    while (this.m_Pause)
                    {
                        await Task.Delay(nPauseCheckMs);
                    }


                    // take the queue
                    KeyValuePair <string, IReliableQueue <Wi> > kvp = this.m_WorkManager.m_QueueManager.TakeQueueAsync();

                    if (null == kvp.Value) // no queue to work on.
                    {
                        // this will only happen if executers # are > than queues
                        // usually a situation that should resolve it self.
                        // well by the following logic
                        this.m_WorkManager.m_TraceWriter.TraceMessage(
                            string.Format("Executer {0} found no q and will sleep for {1}", this.m_WorkerExecuterId, nNoQueueWaitTimeMS));

                        await this.FinilizeQueueWork(0, null, null); // check removal

                        await Task.Delay(nNoQueueWaitTimeMS);        // sleep as there is no point of retrying right away.

                        continue;
                    }

                    // got Q
                    IReliableQueue <Wi> q  = kvp.Value;
                    string qName           = kvp.Key;
                    int    nCurrentMessage = 0;

                    try
                    {
                        while (this.m_KeepWorking & !this.m_Pause)
                        {
                            nCurrentMessage++;

                            // processed the # of messages?
                            if (nCurrentMessage > this.m_WorkManager.YieldQueueAfter)
                            {
                                break; //-> to finally
                            }

                            // as long as we have other queues. we need to have a short wait time
                            int ActualTimeOut = this.m_WorkManager.m_QueueManager.Count > this.m_WorkManager.m_Executers.Count
                                ? nShortDequeueWaitTimeMs
                                : nLongDequeueWaitTimeMs;


                            using (ITransaction tx = this.m_WorkManager.StateManager.CreateTransaction())
                            {
                                ConditionalResult <Wi> cResults = await q.TryDequeueAsync(
                                    tx,
                                    TimeSpan.FromMilliseconds(ActualTimeOut),
                                    CancellationToken.None);

                                if (cResults.HasValue)
                                {
                                    Handler handler = this.m_WorkManager.GetHandlerForQueue(qName);
                                    Wi      wi      = await handler.HandleWorkItem(cResults.Value);

                                    if (null != wi) // do we have an enqueue request?
                                    {
                                        await q.EnqueueAsync(tx, wi);
                                    }

                                    await tx.CommitAsync();

                                    this.m_WorkManager.DecreaseBufferedWorkItems();
                                }
                                else
                                {
                                    break; // -> to finally
                                }
                            }
                        }
                    }
                    catch (TimeoutException to)
                    {
                        /* Queue is locked for enqueues */
                        this.m_WorkManager.m_TraceWriter.TraceMessage(
                            string.Format("Executer Dequeue Timeout after {0}: {1}", nLongDequeueWaitTimeMs, to.Message));
                        break; //-> to finally
                    }
                    catch (AggregateException aex)
                    {
                        AggregateException ae = aex.Flatten();
                        this.m_WorkManager.m_TraceWriter.TraceMessage(
                            string.Format(
                                "Executer encountered fatel error and will exit E:{0} StackTrace:{1}",
                                ae.GetCombinedExceptionMessage(),
                                ae.GetCombinedExceptionStackTrace()));

                        throw;
                    }
                    catch (Exception E)
                    {
                        this.m_WorkManager.m_TraceWriter.TraceMessage(
                            string.Format("Executer encountered fatel error and will exit E:{0} StackTrace:{1}", E.Message, E.StackTrace));

                        throw;
                    }
                    finally
                    {
                        await this.FinilizeQueueWork(nCurrentMessage, qName, q);
                    }
                }

                this.m_WorkManager.m_TraceWriter.TraceMessage(string.Format("Worker {0} exited loop", this.m_WorkerExecuterId));
            }
Ejemplo n.º 19
0
        /// <summary>
        /// Performs the main processing work.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            try
            {
                IReliableQueue <ReportProcessingStep> processQueue
                    = await this.StateManager.GetOrAddAsync <IReliableQueue <ReportProcessingStep> >(ProcessingQueueName);

                IReliableDictionary <string, ReportStatus> statusDictionary
                    = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, ReportStatus> >(StatusDictionaryName);

                // First time setup: queue up all the processing steps and create an initial processing status if one doesn't exist already
                // Note that this will execute every time a replica is promoted to primary,
                // so we need to check to see if it's already been done because we only want to initialize once.
                using (ITransaction tx = this.StateManager.CreateTransaction())
                {
                    ConditionalValue <ReportStatus> tryGetResult
                        = await statusDictionary.TryGetValueAsync(tx, this.reportContext.Name, LockMode.Update);

                    if (!tryGetResult.HasValue)
                    {
                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Creating"));

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Evaluating"));

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Reticulating"));

                        for (int i = 0; i < processingMultiplier * queueLengthMultiplier; ++i)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            await processQueue.EnqueueAsync(tx, new ReportProcessingStep($"Processing {i}"));
                        }

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Sanitizing"));

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Mystery Step"));

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Finalizing"));

                        await processQueue.EnqueueAsync(tx, new ReportProcessingStep("Complete"));

                        await statusDictionary.AddAsync(tx, this.reportContext.Name, new ReportStatus(0, processingMultiplier *queueLengthMultiplier + 7, "Not started.", String.Empty));
                    }

                    await tx.CommitAsync();
                }

                // start processing and checkpoint between each step so we don't lose any progress in the event of a fail-over
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    try
                    {
                        // Get the next step from the queue with a peek.
                        // This keeps the item on the queue in case processing fails.
                        ConditionalValue <ReportProcessingStep> dequeueResult;
                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            dequeueResult = await processQueue.TryPeekAsync(tx, LockMode.Default);
                        }

                        if (!dequeueResult.HasValue)
                        {
                            // all done!
                            break;
                        }

                        ReportProcessingStep currentProcessingStep = dequeueResult.Value;

                        ServiceEventSource.Current.ServiceMessage(
                            this.Context,
                            $"Processing step: {currentProcessingStep.Name}");

                        // Get the current processing step
                        ConditionalValue <ReportStatus> dictionaryGetResult;
                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            dictionaryGetResult = await statusDictionary.TryGetValueAsync(tx, this.reportContext.Name, LockMode.Default);
                        }

                        // Perform the next processing step.
                        // This is potentially a long-running operation, therefore it is not executed within a transaction.
                        ReportStatus currentStatus = dictionaryGetResult.Value;
                        ReportStatus newStatus     = await this.ProcessReport(currentStatus, currentProcessingStep, cancellationToken);

                        // Once processing is done, save the results and dequeue the processing step.
                        // If an exception or other failure occurs at this point, the processing step will run again.
                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            dequeueResult = await processQueue.TryDequeueAsync(tx);

                            await statusDictionary.SetAsync(tx, this.reportContext.Name, newStatus);

                            await tx.CommitAsync();
                        }

                        ServiceEventSource.Current.ServiceMessage(
                            this.Context,
                            $"Processing step: {currentProcessingStep.Name} complete.");
                    }
                    catch (TimeoutException)
                    {
                        // transient error. Retry.
                        ServiceEventSource.Current.ServiceMessage(this.Context, "TimeoutException in RunAsync.");
                    }
                    catch (FabricTransientException fte)
                    {
                        // transient error. Retry.
                        ServiceEventSource.Current.ServiceMessage(this.Context, "FabricTransientException in RunAsync: {0}", fte.Message);
                    }
                    catch (FabricNotReadableException)
                    {
                        // retry or wait until not primary
                        ServiceEventSource.Current.ServiceMessage(this.Context, "FabricNotReadableException in RunAsync.");
                    }

                    // delay between each to step to prevent starving other processing service instances.
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                }

                ServiceEventSource.Current.ServiceMessage(
                    this.Context,
                    $"Processing complete!");
            }
            catch (OperationCanceledException)
            {
                // time to quit
                throw;
            }
            catch (FabricNotPrimaryException)
            {
                // time to quit
                return;
            }
            catch (Exception ex)
            {
                // all other exceptions: log and re-throw.
                ServiceEventSource.Current.ServiceMessage(this.Context, "Exception in RunAsync: {0}", ex.Message);

                throw;
            }
        }
Ejemplo n.º 20
0
        public async Task <IActionResult> Post(string deviceId, [FromBody] IEnumerable <DeviceEvent> events)
        {
            if (String.IsNullOrEmpty(deviceId))
            {
                return(this.BadRequest());
            }

            if (events == null)
            {
                return(this.BadRequest());
            }

            ServiceEventSource.Current.ServiceMessage(
                this.context,
                "Received {0} events from device {1}",
                events.Count(),
                deviceId);

            DeviceEvent max = events.FirstOrDefault();

            if (max == null)
            {
                return(this.Ok());
            }

            DeviceEventSeries eventList = new DeviceEventSeries(deviceId, events);

            IReliableDictionary <string, DeviceEvent> store =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <string, DeviceEvent> >(DataService.EventDictionaryName);

            IReliableQueue <DeviceEventSeries> queue =
                await this.stateManager.GetOrAddAsync <IReliableQueue <DeviceEventSeries> >(DataService.EventQueueName);

            // determine the most recent event in the time series
            foreach (DeviceEvent item in events)
            {
                this.appLifetime.ApplicationStopping.ThrowIfCancellationRequested();

                if (item.Timestamp > max.Timestamp)
                {
                    max = item;
                }
            }

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                // Update the current value if the max in the new set is more recent
                // Or add the max in the current set if a value for this device doesn't exist.
                await store.AddOrUpdateAsync(
                    tx,
                    deviceId,
                    max,
                    (key, currentValue) =>
                {
                    return(max.Timestamp > currentValue.Timestamp
                            ? max
                            : currentValue);
                });

                // Queue the time series for offload
                await queue.EnqueueAsync(tx, eventList);

                // Commit
                await tx.CommitAsync();
            }

            return(this.Ok());
        }
        public async Task EnqueueAsync(ITransaction tx, T item)
        {
            await queue.EnqueueAsync(tx, item);

            signal.Release();
        }