Exemple #1
0
            private static bool HasConditional(string content, string[] conditionals, string sign, out ConditionalResult result)
            {
                result = new ConditionalResult();

                foreach (var _keyword in conditionals)
                {
                    string keyword = $" {_keyword} ";

                    if (content.IndexOf(keyword) == -1)
                    {
                        continue;
                    }

                    var index = content.IndexOf(keyword);
                    while (index != -1)
                    {
                        if (!FiMHelper.IsIndexInsideString(content, index))
                        {
                            result.Keyword = keyword;
                            result.Sign    = sign;
                            result.Index   = index;
                            return(true);
                        }

                        var newIndex = content.IndexOf(keyword, index);
                        if (newIndex == index)
                        {
                            break;
                        }
                        index = newIndex;
                    }
                }
                return(false);
            }
        /// <summary>
        /// This is the main entry point for your service's partition replica.
        /// RunAsync executes when the primary replica for this partition has write status.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric terminates this partition's replica.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            var queryModelBuilder = GetQueryModelBuilder();
            var queue             = await StateManager.GetOrAddAsync <IReliableQueue <string> >("queryModelBuilderQueue");

            var count = (int)await queue.GetCountAsync();

            if (count > 0)
            {
                _semaphore.Release(count);
            }

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                using (ITransaction tx = StateManager.CreateTransaction())
                {
                    ConditionalResult <string> dequeueReply = await queue.TryDequeueAsync(tx);

                    if (dequeueReply.HasValue)
                    {
                        string message = dequeueReply.Value;
                        await queryModelBuilder.Handle(CqrsApplication.GetService <IDeserializer>().CreateEvent(JObject.Parse(message)));

                        await tx.CommitAsync();
                    }
                }

                await _semaphore.WaitAsync(cancellationToken);
            }
        }
        protected async Task <Processor> GetProcessorAsync(string ProcessorName, ITransaction tx = null)
        {
            ITransaction _trx = tx ?? this.Svc.StateManager.CreateTransaction();


            Processor processor;
            ConditionalResult <Processor> cResult = await this.Svc.ProcessorStateStore.TryGetValueAsync(_trx, ProcessorName);

            if (cResult.HasValue)
            {
                processor = cResult.Value;
            }
            else
            {
                processor = null;
            }

            if (null == tx)
            {
                await _trx.CommitAsync();

                _trx.Dispose();
            }

            return(processor);
        }
Exemple #4
0
        public async Task <HttpResponseMessage> GetFullTelemetryFrame(int id)
        {
            if (id == 0)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "No Data"));
            }


            var dataCollection = await _reliableStateManager.GetOrAddAsync <IReliableDictionary <int, Telemetry> >(String.Format("VehicleId-{0}", id));

            using (ITransaction transaction = _reliableStateManager.CreateTransaction())
            {
                ConditionalResult <Telemetry> result = await dataCollection.TryGetValueAsync(transaction, 0);

                if (result.HasValue)
                {
                    HttpResponseMessage httpResponseMessage = Request.CreateResponse <Telemetry>(result.Value);
                    httpResponseMessage.StatusCode = HttpStatusCode.Found;
                    return(httpResponseMessage);
                }
                else
                {
                    HttpResponseMessage httpResponseMessage = Request.CreateResponse();
                    httpResponseMessage.StatusCode = HttpStatusCode.NotFound;
                    return(httpResponseMessage);
                }
            }
        }
        public static async Task <StateManagerLease> GetOrCreateAsync(
            IReliableStateManager StateManager,
            IReliableDictionary <string, string> StateDictionary,
            string EntryName,
            string partitionId)
        {
            using (ITransaction tx = StateManager.CreateTransaction())
            {
                StateManagerLease lease;
                // if something has been saved before load it
                ConditionalResult <string> cResults = await StateDictionary.TryGetValueAsync(tx, EntryName);

                if (cResults.HasValue)
                {
                    lease = FromJsonString(cResults.Value);
                    lease.m_StateDictionary = StateDictionary;
                    lease.m_StateManager    = StateManager;
                }
                else
                {
                    // if not create new
                    lease = new StateManagerLease(StateManager, StateDictionary, EntryName, partitionId);
                }
                await tx.CommitAsync();

                return(lease);
            }
        }
        public async Task <Processor> Stop([FromUri] string ProcessorName)
        {
            string[] validationErrors = Processor.ValidateProcessName(ProcessorName);
            if (null != validationErrors)
            {
                Utils.ThrowHttpError(validationErrors);
            }


            Processor existing;

            using (ITransaction tx = this.Svc.StateManager.CreateTransaction())
            {
                // do we have it?
                ConditionalResult <Processor> cResults = await this.Svc.ProcessorStateStore.TryGetValueAsync(tx, ProcessorName);

                if (!cResults.HasValue)
                {
                    Utils.ThrowHttpError(string.Format("processor with the name {0} does not exists", ProcessorName));
                }

                existing = cResults.Value;


                if (existing.IsOkToQueueOperation())
                {
                    Utils.ThrowHttpError(
                        string.Format("Processor with the name {0} not valid for this operation", ProcessorName, existing.ProcessorStatusString));
                }

                existing.ProcessorStatus |= ProcessorStatus.PendingStop;

                existing = await this.Svc.ProcessorStateStore.AddOrUpdateAsync(
                    tx,
                    existing.Name,
                    existing,
                    (name, proc) =>
                {
                    proc.SafeUpdate(existing);
                    return(proc);
                });


                await
                this.Svc.ProcessorOperationsQueue.EnqueueAsync(
                    tx,
                    new ProcessorOperation()
                {
                    OperationType = ProcessorOperationType.Stop, ProcessorName = ProcessorName
                });

                await tx.CommitAsync();


                ServiceEventSource.Current.Message(string.Format("Queued stop command for processor {0} ", existing.Name));
            }

            return(existing);
        }
Exemple #7
0
        public async Task <HttpResponseMessage> TelemetryIngest([FromBody] Telemetry telemetry)
        {
            if (telemetry == null)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "No Data"));
            }

            var dataCollection = await _reliableStateManager.GetOrAddAsync <IReliableDictionary <int, Telemetry> >(String.Format("VehicleId-{0}", telemetry.Id));

            bool fullFrameIngest = (telemetry.MessageNumber % 10 == 0) || (telemetry.MessageNumber == 1);

            Telemetry fullTelemetry = new Telemetry();

            if (fullFrameIngest)
            {
                fullTelemetry = telemetry;
            }
            else
            {
                using (ITransaction transaction = _reliableStateManager.CreateTransaction())
                {
                    ConditionalResult <Telemetry> result = await dataCollection.TryGetValueAsync(transaction, 0);

                    if (result.HasValue)
                    {
                        fullTelemetry = result.Value;
                    }
                }

                fullTelemetry.Speed = telemetry.Speed ?? fullTelemetry.Speed;
                fullTelemetry.EmergencySituation = telemetry.EmergencySituation ?? fullTelemetry.EmergencySituation;
                fullTelemetry.PoIType            = telemetry.PoIType ?? fullTelemetry.PoIType;
                fullTelemetry.Latitude           = telemetry.Latitude == 0 ? fullTelemetry.Latitude : telemetry.Latitude;
                fullTelemetry.Longitude          = telemetry.Longitude == 0 ? fullTelemetry.Longitude : telemetry.Longitude;
            }


            using (ITransaction transaction = _reliableStateManager.CreateTransaction())
            {
                ConditionalResult <Telemetry> result = await dataCollection.TryGetValueAsync(transaction, 0);

                if (!result.HasValue)
                {
                    await dataCollection.TryAddAsync(transaction, 0, fullTelemetry);
                }
                else
                {
                    await dataCollection.AddOrUpdateAsync(transaction, 0, fullTelemetry, (int key, Telemetry data) => fullTelemetry);
                }

                await transaction.CommitAsync();
            }

            //TODO: Add EventHub Ingest

            return(Request.CreateResponse(HttpStatusCode.Created));
        }
Exemple #8
0
        public async Task JoinClusterAsync(string username, string clusterName)
        {
            if (String.IsNullOrWhiteSpace(username))
            {
                throw new ArgumentNullException("username");
            }

            if (String.IsNullOrWhiteSpace(clusterName))
            {
                throw new ArgumentNullException("clusterName");
            }

            IReliableDictionary <string, Cluster> clusterDictionary =
                await this.reliableStateManager.GetOrAddAsync <IReliableDictionary <string, Cluster> >(ClusterDictionaryName);

            int    userPort;
            string clusterAddress;

            using (ITransaction tx = this.reliableStateManager.CreateTransaction())
            {
                ConditionalResult <Cluster> result = await clusterDictionary.TryGetValueAsync(tx, clusterName, LockMode.Update);

                if (!result.HasValue)
                {
                    throw new KeyNotFoundException();
                }

                Cluster cluster = result.Value;

                // make sure the cluster is ready
                if (cluster.Status != ClusterStatus.Ready)
                {
                    throw new InvalidOperationException(); // need a better exception here
                }

                // make sure the cluster isn't about to be deleted.
                if ((DateTimeOffset.UtcNow - cluster.CreatedOn.ToUniversalTime()) > (this.Config.MaxClusterUptime - TimeSpan.FromMinutes(5)))
                {
                    throw new InvalidOperationException(); // need a better exception here
                }

                userPort       = cluster.Ports.First(port => !cluster.Users.Select(x => x.Port).Contains(port));
                clusterAddress = cluster.Address;

                cluster.Users.Add(new ClusterUser()
                {
                    Name = username, Port = userPort
                });

                await clusterDictionary.SetAsync(tx, clusterName, cluster);

                await tx.CommitAsync();
            }

            // send email to user with cluster info
        }
        public async Task <Processor> Add([FromUri] string ProcessorName, [FromBody] Processor processor)
        {
            processor.Name = ProcessorName;

            string[] validationErrors = processor.Validate();
            if (null != validationErrors)
            {
                Utils.ThrowHttpError(validationErrors);
            }


            processor.ProcessorStatus = ProcessorStatus.New;

            using (ITransaction tx = this.Svc.StateManager.CreateTransaction())
            {
                // do we have it?
                ConditionalResult <Processor> cResults = await this.Svc.ProcessorStateStore.TryGetValueAsync(tx, processor.Name);

                if (cResults.HasValue)
                {
                    Utils.ThrowHttpError(
                        string.Format("Processor with the name {0} currently exists with status", processor.Name),
                        string.Format(
                            "Processor {0} is currently {1} and mapped to app {2}",
                            cResults.Value.Name,
                            cResults.Value.ProcessorStatus.ToString(),
                            cResults.Value.ServiceFabricAppInstanceName));
                }

                // save it
                await this.Svc.ProcessorStateStore.AddAsync(tx, processor.Name, processor);

                // create it it
                await
                this.Svc.ProcessorOperationsQueue.EnqueueAsync(
                    tx,
                    new ProcessorOperation()
                {
                    OperationType = ProcessorOperationType.Add, ProcessorName = processor.Name
                });


                await tx.CommitAsync();

                ServiceEventSource.Current.Message(string.Format("Queued create for processor {0} ", processor.Name));
            }


            return(processor);
        }
        public async Task <List <ProcessorRuntimeStatus> > GetDetailedStatus([FromUri] string ProcessorName)
        {
            string[] validationErrors = Processor.ValidateProcessName(ProcessorName);
            if (null != validationErrors)
            {
                Utils.ThrowHttpError(validationErrors);
            }

            Processor processor;

            using (ITransaction tx = this.Svc.StateManager.CreateTransaction())
            {
                // do we have it?
                ConditionalResult <Processor> cResults = await this.Svc.ProcessorStateStore.TryGetValueAsync(tx, ProcessorName);

                if (!cResults.HasValue)
                {
                    Utils.ThrowHttpError(string.Format("Processor with the name {0} does not exist", ProcessorName));
                }

                processor = cResults.Value;
            }

            ProcessorOperationHandlerFactory factory          = new ProcessorOperationHandlerFactory();
            ProcessorOperationHandlerBase    operationHandler = factory.CreateHandler(
                this.Svc,
                new ProcessorOperation()
            {
                OperationType = ProcessorOperationType.RuntimeStatusCheck, ProcessorName = ProcessorName
            });

            List <ProcessorRuntimeStatus> runtimeStatus = new List <ProcessorRuntimeStatus>();

            Task <HttpResponseMessage>[] tasks = await operationHandler.ExecuteOperation <Task <HttpResponseMessage>[]>(null);

            await Task.WhenAll(tasks);

            foreach (Task <HttpResponseMessage> completedTask in tasks)
            {
                HttpResponseMessage httpResponse = completedTask.Result;
                if (!httpResponse.IsSuccessStatusCode)
                {
                    Utils.ThrowHttpError("error aggregating status from processor partitions");
                }

                runtimeStatus.Add(JsonConvert.DeserializeObject <ProcessorRuntimeStatus>(await httpResponse.Content.ReadAsStringAsync()));
            }
            return(runtimeStatus);
        }
Exemple #11
0
        public async Task <bool> IsItemInInventoryAsync(InventoryItemId itemId)
        {
            ServiceEventSource.Current.Message("checking item {0} to see if it is in inventory", itemId);
            IReliableDictionary <InventoryItemId, InventoryItem> inventoryItems =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <InventoryItemId, InventoryItem> >(InventoryItemDictionaryName);

            PrintInventoryItems(inventoryItems);

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                ConditionalResult <InventoryItem> item = await inventoryItems.TryGetValueAsync(tx, itemId);

                return(item.HasValue);
            }
        }
        public async Task <IHttpActionResult> Count()
        {
            IReliableDictionary <string, long> statsDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, long> >("statsDictionary");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                ConditionalResult <long> result = await statsDictionary.TryGetValueAsync(tx, "Number of Words Processed");

                if (result.HasValue)
                {
                    return(this.Ok(result.Value));
                }
            }

            return(this.Ok(0));
        }
        public ConditionalResult <TValue> TryRemove(ITransaction tx, TKey key, long version = -1)
        {
            var transaction = tx.GetTransaction();

            var       id = Interlocked.Increment(ref this.operationNumber);
            Operation undo;
            var       dbTransaction = this.tables.CreateTransaction();
            ConditionalResult <TValue> result;

            try
            {
                TValue initialValue;
                if (dbTransaction.Table.TryGetValue(key, out initialValue))
                {
                    undo = new SetOperation {
                        Key = key, Value = initialValue, Id = id
                    };
                    result = new ConditionalResult <TValue>(true, initialValue);
                }
                else
                {
                    undo   = NopOperation.Instance;
                    result = new ConditionalResult <TValue>();
                }
            }
            catch
            {
                dbTransaction.Rollback();
                dbTransaction.Dispose();
                throw;
            }

            var redo = new RemoveOperation {
                Key = key, Id = id
            };

            this.PerformOperation <object>(
                id,
                new OperationContext {
                DatabaseTransaction = dbTransaction, ReplicatorTransaction = transaction
            },
                undo,
                redo);

            return(result);
        }
        private async Task <Processor> GetAssignedProcessorFromState()
        {
            Processor processor = null;
            IReliableDictionary <string, string> dict = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, string> >(DefDictionary);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalResult <string> cResult = await dict.TryGetValueAsync(tx, AssignedProcessorEntryName);

                if (cResult.HasValue)
                {
                    processor = Processor.FromJsonString(cResult.Value);
                }
                await tx.CommitAsync();
            }
            return(processor);
        }
Exemple #15
0
        public ConditionalResult <T> Get <T>(string key)
            where T : class
        {
            var cachedObject = _cache.Get(key);

            if (cachedObject?.Value != null)
            {
                if (_cloningProvider.RequireCloning(cachedObject.Value.GetType()))
                {
                    return(ConditionalResult.CreateSuccessful(_cloningProvider.Clone(cachedObject.Value as T)));
                }

                return(ConditionalResult.CreateSuccessful(cachedObject.Value as T));
            }

            return(ConditionalResult.CreateFailure <T>());
        }
Exemple #16
0
        async Task <IEnumerable <string> > ISimpleStatefulService.GetStrings()
        {
            var queue = await StateManager.GetOrAddAsync <IReliableQueue <string> >(QueueName);

            var strings = new List <string>(25);

            using (var tx = StateManager.CreateTransaction())
            {
                ConditionalResult <string> s = await queue.TryDequeueAsync(tx);

                while (s.HasValue)
                {
                    strings.Add(s.Value);
                    s = await queue.TryDequeueAsync(tx);
                }
                await tx.CommitAsync();
            }

            return(strings);
        }
Exemple #17
0
        /// <summary>
        /// Tries to add the given quantity to the inventory item with the given ID without going over the maximum quantity allowed for an item.
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="quantity"></param>
        /// <returns>The quantity actually added to the item.</returns>
        public async Task <int> AddStockAsync(InventoryItemId itemId, int quantity)
        {
            IReliableDictionary <InventoryItemId, InventoryItem> inventoryItems =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <InventoryItemId, InventoryItem> >(InventoryItemDictionaryName);

            int quantityAdded = 0;

            ServiceEventSource.Current.ServiceMessage(this, "Received add stock request. Item: {0}. Quantity: {1}.", itemId, quantity);

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                // Try to get the InventoryItem for the ID in the request.
                ConditionalResult <InventoryItem> item = await inventoryItems.TryGetValueAsync(tx, itemId);

                // We can only update the stock for InventoryItems in the system - we are not adding new items here.
                if (item.HasValue)
                {
                    // Update the stock quantity of the item.
                    // This only updates the copy of the Inventory Item that's in local memory here;
                    // It's not yet saved in the dictionary.
                    quantityAdded = item.Value.AddStock(quantity);

                    // We have to store the item back in the dictionary in order to actually save it.
                    // This will then replicate the updated item for
                    await inventoryItems.SetAsync(tx, item.Value.Id, item.Value);
                }

                // nothing will happen unless we commit the transaction!
                await tx.CommitAsync();

                ServiceEventSource.Current.ServiceMessage(
                    this,
                    "Add stock complete. Item: {0}. Added: {1}. Total: {2}",
                    item.Value.Id,
                    quantityAdded,
                    item.Value.AvailableStock);
            }


            return(quantityAdded);
        }
        public async Task <Processor> Get([FromUri] string ProcessorName)
        {
            string[] validationErrors = Processor.ValidateProcessName(ProcessorName);
            if (null != validationErrors)
            {
                Utils.ThrowHttpError(validationErrors);
            }


            using (ITransaction tx = this.Svc.StateManager.CreateTransaction())
            {
                // do we have it?
                ConditionalResult <Processor> cResults = await this.Svc.ProcessorStateStore.TryGetValueAsync(tx, ProcessorName);

                if (!cResults.HasValue)
                {
                    Utils.ThrowHttpError(string.Format("Processor with the name {0} does not exist", ProcessorName));
                }

                return(cResults.Value);
            }
        }
Exemple #19
0
        /// <summary>
        /// This is the main entry point for your service's partition replica.
        /// RunAsync executes when the primary replica for this partition has write status.
        /// </summary>
        /// <param name="cancellationToken">Canceled when Service Fabric terminates this partition's replica.</param>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            var queue = await StateManager.GetOrAddAsync <IReliableQueue <string> >("eventBusQueue");

            // We use the ServiceFabricEventBus as our way of dispatching in this service.
            // The class has all the registered builders and can locate them through the ServiceClient.

            var eventBus = new ServiceFabricEventBus();

            Handlers.QueryModelBuilders.ToList().ForEach(eventBus.RegisterBuilder);
            var deserializer = new Deserializer();

            var count = (int)await queue.GetCountAsync();

            if (count > 0)
            {
                _semaphore.Release(count);
            }

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                using (ITransaction tx = StateManager.CreateTransaction())
                {
                    ConditionalResult <string> dequeueReply = await queue.TryDequeueAsync(tx);

                    if (dequeueReply.HasValue)
                    {
                        string message = dequeueReply.Value;
                        await eventBus.Dispatch(deserializer.CreateEvent(JObject.Parse(message)));

                        await tx.CommitAsync();
                    }
                }

                await _semaphore.WaitAsync(cancellationToken);
            }
        }
Exemple #20
0
            public static bool GetConditional(string content, out ConditionalResult result)
            {
                if (HasConditional(content, And, "&&", out result))
                {
                    return(true);
                }
                if (HasConditional(content, Or, "||", out result))
                {
                    return(true);
                }
                if (HasConditional(content, LessThanEqual, "<=", out result))
                {
                    return(true);
                }
                if (HasConditional(content, GreaterThanEqual, ">=", out result))
                {
                    return(true);
                }
                if (HasConditional(content, GreaterThan, ">", out result))
                {
                    return(true);
                }
                if (HasConditional(content, LessThan, "<", out result))
                {
                    return(true);
                }
                if (HasConditional(content, Not, "!=", out result))
                {
                    return(true);
                }
                if (HasConditional(content, Equal, "==", out result))
                {
                    return(true);
                }

                return(false);
            }
Exemple #21
0
        /// <inheritdoc/>
        public ConditionalResult <T> Get <T>(string key)
            where T : class
        {
            CachedObject cachedObject = _cache.Get(key);

            if (cachedObject == null)
            {
                return(ConditionalResult.CreateFailure <T>());
            }

            if (cachedObject.Value == null)
            {
                return(ConditionalResult.CreateSuccessful <T>(null));
            }

            var castedValue = cachedObject.Value as T;

            if (castedValue == null)
            {
                return(ConditionalResult.CreateFailure <T>());
            }

            return(ConditionalResult.CreateSuccessful(castedValue));
        }
Exemple #22
0
        /// <summary>
        /// Drains the queue of completed restock requests sends them to InventoryService.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            IReliableQueue <RestockRequest> completedRequests = await this.StateManager.GetOrAddAsync <IReliableQueue <RestockRequest> >(CompletedRequestsQueueName);

            while (!cancellationToken.IsCancellationRequested)
            {
                using (ITransaction tx = this.StateManager.CreateTransaction())
                {
                    ConditionalResult <RestockRequest> result = await completedRequests.TryDequeueAsync(tx, TxTimeout, cancellationToken);

                    if (result.HasValue)
                    {
                        ServiceUriBuilder builder          = new ServiceUriBuilder(InventoryServiceName);
                        IInventoryService inventoryService = ServiceProxy.Create <IInventoryService>(result.Value.ItemId.GetPartitionKey(), builder.ToUri());

                        await inventoryService.AddStockAsync(result.Value.ItemId, result.Value.Quantity);

                        ServiceEventSource.Current.ServiceMessage(
                            this,
                            "Adding stock to inventory service. ID: {0}. Quantity: {1}",
                            result.Value.ItemId,
                            result.Value.Quantity);
                    }

                    // This commits the dequeue operations.
                    // If the request to add the stock to the inventory service throws, this commit will not execute
                    // and the items will remain on the queue, so we can be sure that we didn't dequeue items
                    // that didn't get saved successfully in the inventory service.
                    // However there is a very small chance that the stock was added to the inventory service successfully,
                    // but service execution stopped before reaching this commit (machine crash, for example).
                    await tx.CommitAsync();
                }

                await Task.Delay(CompletedRequestsBatchInterval, cancellationToken);
            }
        }
Exemple #23
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));
            }
Exemple #24
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            this.SetProcessorAppInstanceDefaults();

            // subscribe to configuration changes
            this.ServiceInitializationParameters.CodePackageActivationContext.ConfigurationPackageModifiedEvent +=
                this.CodePackageActivationContext_ConfigurationPackageModifiedEvent;

            this.ProcessorStateStore = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, Processor> >(ProcessorDefinitionStateDictionaryName);

            this.ProcessorOperationsQueue = await this.StateManager.GetOrAddAsync <IReliableQueue <ProcessorOperation> >(OperationQueueName);

            this.ProcessorOperationFactory = new ProcessorOperationHandlerFactory();

            ProcessorOperation processorOperation = null;

            // pump and execute ProcessorPperation from the queue
            while (!cancellationToken.IsCancellationRequested)
            {
                using (ITransaction tx = this.StateManager.CreateTransaction())
                {
                    try
                    {
                        ConditionalResult <ProcessorOperation> result = await this.ProcessorOperationsQueue.TryDequeueAsync(
                            tx,
                            TimeSpan.FromMilliseconds(1000),
                            cancellationToken);

                        if (result.HasValue)
                        {
                            processorOperation = result.Value;
                            ProcessorOperationHandlerBase handler = this.ProcessorOperationFactory.CreateHandler(this, processorOperation);
                            await handler.RunOperation(tx);

                            await tx.CommitAsync();
                        }
                    }
                    catch (TimeoutException toe)
                    {
                        ServiceEventSource.Current.Message(
                            string.Format("Controller service encountered timeout in a work operations de-queue process {0} and will try again", toe.StackTrace));
                    }
                    catch (AggregateException aex)
                    {
                        AggregateException ae = aex.Flatten();

                        string sError = string.Empty;
                        if (null == processorOperation)
                        {
                            sError =
                                string.Format(
                                    "Event Processor Management Service encountered an error processing Processor-Operation {0} {1} and will terminate replica",
                                    ae.GetCombinedExceptionMessage(),
                                    ae.GetCombinedExceptionStackTrace());
                        }
                        else
                        {
                            sError =
                                string.Format(
                                    "Event Processor Management Service encountered an error processing Processor-opeartion {0} against {1} Error {2} stack trace {3} and will terminate replica",
                                    processorOperation.OperationType.ToString(),
                                    processorOperation.ProcessorName,
                                    ae.GetCombinedExceptionMessage(),
                                    ae.GetCombinedExceptionStackTrace());
                        }


                        ServiceEventSource.Current.ServiceMessage(this, sError);
                        throw;
                    }
                }
            }
        }
 /// <inheritdoc/>
 public ConditionalResult <T> Get <T>(string key)
     where T : class
 {
     return(ConditionalResult.CreateFailure <T>());
 }
Exemple #26
0
        /// <summary>
        /// Removes the given quantity of stock from an in item in the inventory.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>int: Returns the quantity removed from stock.</returns>
        public async Task <int> RemoveStockAsync(InventoryItemId itemId, int quantity, CustomerOrderActorMessageId amId)
        {
            ServiceEventSource.Current.ServiceMessage(this, "inside remove stock {0}|{1}", amId.GetHashCode(), amId.GetHashCode());

            IReliableDictionary <InventoryItemId, InventoryItem> inventoryItems =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <InventoryItemId, InventoryItem> >(InventoryItemDictionaryName);

            IReliableDictionary <CustomerOrderActorMessageId, DateTime> recentRequests =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <CustomerOrderActorMessageId, DateTime> >(ActorMessageDictionaryName);

            IReliableDictionary <CustomerOrderActorMessageId, Tuple <InventoryItemId, int> > requestHistory =
                await
                this.stateManager.GetOrAddAsync <IReliableDictionary <CustomerOrderActorMessageId, Tuple <InventoryItemId, int> > >(RequestHistoryDictionaryName);

            int removed = 0;

            ServiceEventSource.Current.ServiceMessage(this, "Received remove stock request. Item: {0}. Quantity: {1}.", itemId, quantity);

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                //first let's see if this is a duplicate request
                ConditionalResult <DateTime> previousRequest = await recentRequests.TryGetValueAsync(tx, amId);

                if (!previousRequest.HasValue)
                {
                    //first time we've seen the request or it was a dupe from so long ago we have forgotten

                    // Try to get the InventoryItem for the ID in the request.
                    ConditionalResult <InventoryItem> item = await inventoryItems.TryGetValueAsync(tx, itemId);

                    // We can only remove stock for InventoryItems in the system.
                    if (item.HasValue)
                    {
                        // Update the stock quantity of the item.
                        // This only updates the copy of the Inventory Item that's in local memory here;
                        // It's not yet saved in the dictionary.
                        removed = item.Value.RemoveStock(quantity);

                        // We have to store the item back in the dictionary in order to actually save it.
                        // This will then replicate the updated item
                        await inventoryItems.SetAsync(tx, itemId, item.Value);

                        //we also have to make a note that we have returned this result, so that we can protect
                        //ourselves from stale or duplicate requests that come back later
                        await requestHistory.SetAsync(tx, amId, new Tuple <InventoryItemId, int>(itemId, removed));

                        ServiceEventSource.Current.ServiceMessage(
                            this,
                            "Removed stock complete. Item: {0}. Removed: {1}. Remaining: {2}",
                            item.Value.Id,
                            removed,
                            item.Value.AvailableStock);
                    }
                }
                else
                {
                    //this is a duplicate request. We need to send back the result we already came up with and hope they get it this time
                    //find the previous result and send it back
                    ConditionalResult <Tuple <InventoryItemId, int> > previousResponse = await requestHistory.TryGetValueAsync(tx, amId);

                    if (previousResponse.HasValue)
                    {
                        removed = previousResponse.Value.Item2;
                        ServiceEventSource.Current.ServiceMessage(
                            this,
                            "Retrieved previous response for request {0}, from {1}, for Item {2} and quantity {3}",
                            amId,
                            previousRequest.Value,
                            previousResponse.Value.Item1,
                            previousResponse.Value.Item2);
                    }
                    else
                    {
                        //we've seen the request before but we don't have a record for what we responded, inconsistent state
                        ServiceEventSource.Current.ServiceMessage(
                            this,
                            "Inconsistent State: recieved duplicate request {0} but don't have matching response in history",
                            amId);
                        this.ServicePartition.ReportFault(System.Fabric.FaultType.Transient);
                    }


                    //note about duplicate Requests: technically if a duplicate request comes in and we have
                    //sufficient invintory to return more now that we did previously, we could return more of the order and decrement
                    //the difference to reduce the total number of round trips. This optimization is not currently implemented
                }


                //always update the datetime for the given request
                await recentRequests.SetAsync(tx, amId, DateTime.UtcNow);

                // nothing will happen unless we commit the transaction!
                ServiceEventSource.Current.Message("Committing Changes in Inventory Service");
                await tx.CommitAsync();

                ServiceEventSource.Current.Message("Inventory Service Changes Committed");
            }

            ServiceEventSource.Current.Message("Removed {0} of item {1}", removed, itemId);
            return(removed);
        }
Exemple #27
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            ServiceEventSource.Current.RunAsyncInvoked(ServiceEventSourceName);

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

            IReliableDictionary <string, long> wordCountDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >("wordCountDictionary");

            IReliableDictionary <string, long> statsDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >("statsDictionary");

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        ConditionalResult <string> dequeuReply = await inputQueue.TryDequeueAsync(tx);

                        if (dequeuReply.HasValue)
                        {
                            string word = dequeuReply.Value;

                            long count = await wordCountDictionary.AddOrUpdateAsync(
                                tx,
                                word,
                                1,
                                (key, oldValue) => oldValue + 1);

                            long numberOfProcessedWords = await statsDictionary.AddOrUpdateAsync(
                                tx,
                                "Number of Words Processed",
                                1,
                                (key, oldValue) => oldValue + 1);

                            long queueLength = await inputQueue.GetCountAsync(tx);

                            await tx.CommitAsync();

                            ServiceEventSource.Current.RunAsyncStatus(
                                this.ServicePartition.PartitionInfo.Id,
                                numberOfProcessedWords,
                                queueLength,
                                word,
                                count);
                        }
                    }

                    await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
                }
                catch (TimeoutException)
                {
                    //Service Fabric uses timeouts on collection operations to prevent deadlocks.
                    //If this exception is thrown, it means that this transaction was waiting the default
                    //amount of time (4 seconds) but was unable to acquire the lock. In this case we simply
                    //retry after a random backoff interval. You can also control the timeout via a parameter
                    //on the collection operation.
                    Thread.Sleep(TimeSpan.FromSeconds(new Random().Next(100, 300)));

                    continue;
                }
                catch (Exception exception)
                {
                    //For sample code only: simply trace the exception.
                    ServiceEventSource.Current.MessageEvent(exception.ToString());
                }
            }
        }