Inheritance: CachedEntity
Beispiel #1
0
        public async Task<StreamHandshakeToken> DeliverBatch(GuidId subscriptionId, Immutable<IBatchContainer> batch, StreamHandshakeToken handshakeToken)
        {
            foreach (var each in batch.Value.GetEvents<object>())
                await handler(each.Item1);

            return null;
        }
        public void Test_That_Original_Object_Cannot_Be_Modified()
        {
            var testClass = new Immutable<TestClass>();
            var newTestClass = testClass.Modify(x => x.Test, 1);

            Assert.Equal(testClass.Get(x => x.Test), 0);
        }
        public void Test_That_Returned_Object_Contains_Modifications()
        {
            var testClass = new Immutable<TestClass>();
            var newTestClass = testClass.Modify(x => x.Test, 2);

            Assert.Equal(newTestClass.Get(x => x.Test), 2);
        }
        public void Test_That_Modifying_Nested_Object_Keeps_Original_Unmodified()
        {
            var testClass = new Immutable<TestClass>();
            var newTestClass = testClass.Modify(x => x.Data, 
                testClass.Get(x => x.Data)
                .Modify(x => x.Member, 2)
            );

            Assert.Equal(testClass.Get(x => x.Data.Get(y => y.Member)), 0);
        }
        /// <summary>
        /// Take responsibility for a new queues that was assigned to me via a new range.
        /// We first store the new queue in our internal data structure, try to initialize it and start a pumping timer.
        /// ERROR HANDLING:
        ///     The resposibility to handle initializatoion and shutdown failures is inside the INewQueueAdapterReceiver code.
        ///     The agent will call Initialize once and log an error. It will not call initiliaze again.
        ///     The receiver itself may attempt later to recover from this error and do initialization again. 
        ///     The agent will assume initialization has succeeded and will subsequently start calling pumping receive.
        ///     Same applies to shutdown.
        /// </summary>
        /// <param name="qAdapter"></param>
        /// <param name="queueAdapterCache"></param>
        /// <param name="failureHandler"></param>
        /// <returns></returns>
        public async Task Initialize(Immutable<IQueueAdapter> qAdapter, Immutable<IQueueAdapterCache> queueAdapterCache, Immutable<IStreamFailureHandler> failureHandler)
        {
            if (qAdapter.Value == null) throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null");
            if (failureHandler.Value == null) throw new ArgumentNullException("failureHandler", "Init: streamDeliveryFailureHandler should not be null");

            logger.Info((int)ErrorCode.PersistentStreamPullingAgent_02, "Init of {0} {1} on silo {2} for queue {3}.",
                GetType().Name, GrainId.ToDetailedString(), Silo, QueueId.ToStringWithHashCode());
            
            // Remove cast once we cleanup
            queueAdapter = qAdapter.Value;
            streamFailureHandler = failureHandler.Value;
            lastTimeCleanedPubSubCache = DateTime.UtcNow;

            try
            {
                receiver = queueAdapter.CreateReceiver(QueueId);
            }
            catch (Exception exc)
            {
                logger.Error((int)ErrorCode.PersistentStreamPullingAgent_02, "Exception while calling IQueueAdapter.CreateNewReceiver.", exc);
                return;
            }

            try
            {
                if (queueAdapterCache.Value != null)
                {
                    queueCache = queueAdapterCache.Value.CreateQueueCache(QueueId);
                }
            }
            catch (Exception exc)
            {
                logger.Error((int)ErrorCode.PersistentStreamPullingAgent_23, "Exception while calling IQueueAdapterCache.CreateQueueCache.", exc);
                return;
            }

            try
            {
                var task = OrleansTaskExtentions.SafeExecute(() => receiver.Initialize(config.InitQueueTimeout));
                task = task.LogException(logger, ErrorCode.PersistentStreamPullingAgent_03, String.Format("QueueAdapterReceiver {0} failed to Initialize.", QueueId.ToStringWithHashCode()));
                await task;
            }
            catch
            {
                // Just ignore this exception and proceed as if Initialize has succeeded.
                // We already logged individual exceptions for individual calls to Initialize. No need to log again.
            }
            // Setup a reader for a new receiver. 
            // Even if the receiver failed to initialise, treat it as OK and start pumping it. It's receiver responsibility to retry initialization.
            var randomTimerOffset = safeRandom.NextTimeSpan(config.GetQueueMsgsTimerPeriod);
            timer = base.RegisterTimer(AsyncTimerCallback, QueueId, randomTimerOffset, config.GetQueueMsgsTimerPeriod);

            logger.Info((int) ErrorCode.PersistentStreamPullingAgent_04, "Taking queue {0} under my responsibility.", QueueId.ToStringWithHashCode());
        }
        /// <summary>
        /// This method checks the list of cached indexes, and if any index does not have a before-image, it will create
        /// one for it. As before-images are stored as an immutable field, a new map is created in this process.
        ///
        /// This method is called on activation of the grain, and when the UpdateIndexes method detects an inconsistency
        /// between the indexes in the index handler and the cached indexes of the current grain.
        /// </summary>
        private void AddMissingBeforeImages()
        {
            IDictionary <string, object> oldBefImgs = this._beforeImages.Value;
            IDictionary <string, object> newBefImgs = new Dictionary <string, object>();

            foreach (var idxOp in this._grainIndexes)
            {
                var indexID   = idxOp.Key;
                var oldBefImg = oldBefImgs.ContainsKey(indexID)
                    ? oldBefImgs[indexID]
                    : idxOp.Value.UpdateGenerator.ExtractIndexImage(this.Properties);
                newBefImgs.Add(indexID, oldBefImg);
            }
            this._beforeImages = newBefImgs.AsImmutable();
        }
Beispiel #7
0
 public Task PingImmutableDictionary(Immutable <Dictionary <int, string> > data, long nextGrain,
                                     bool nextGrainIsRemote)
 {
     if (nextGrain > 0)
     {
         if (nextGrainIsRemote)
         {
             return(this.GrainFactory.GetGrain <IReentrantStressTestGrain>(nextGrain)
                    .PingImmutableDictionary(data, -1, false));
         }
         return(this.GrainFactory.GetGrain <IReentrantLocalStressTestGrain>(nextGrain)
                .PingImmutableDictionary(data, -1, false));
     }
     return(Task.CompletedTask);
 }
        /// <summary>
        /// Upon activation, the list of index update generators is retrieved from the index handler. It is cached in
        /// this grain for use in creating before-images, and also for later calls to UpdateIndexes.
        ///
        /// Then, the before-images are created and stored in memory.
        /// </summary>
        public override Task OnActivateAsync()
        {
            this.Logger.Trace($"Activating indexable grain {base.GrainReference} of type {this.GetIIndexableGrainTypes()[0]} in silo {this.SiloIndexManager.SiloAddress}.");

            // Load indexes
            this._grainIndexes          = this.SiloIndexManager.IndexFactory.GetGrainIndexes(GetIIndexableGrainTypes()[0]);
            this._isThereAnyUniqueIndex = this._grainIndexes.HasAnyUniqueIndex;

            // Initialize before images
            this._beforeImages = new Dictionary <string, object>().AsImmutable <IDictionary <string, object> >();
            AddMissingBeforeImages();

            // Insert the current grain to the active indexes defined on this grain and at the same time call OnActivateAsync of the base class
            return(Task.WhenAll(InsertIntoActiveIndexes(), base.OnActivateAsync()));
        }
        public async Task AddAllToQueue(Immutable <List <IndexWorkflowRecord> > workflowRecords)
        {
            await this.EnsureStorage();

            // Note: this can be called with an empty enumeration, to just "wake up" the thread in FT recovery.
            List <IndexWorkflowRecord> newWorkflows = workflowRecords.Value;

            foreach (IndexWorkflowRecord newWorkflow in newWorkflows)
            {
                AddToQueueNonPersistent(newWorkflow);
            }

            InitiateWorkerThread();
            await(IsFaultTolerant ? PersistState() : Task.CompletedTask);
        }
 /// <summary>
 /// An extension method to intercept the calls to DirectApplyIndexUpdate on an Index
 /// </summary>
 internal static Task <bool> ApplyIndexUpdate(this IIndexInterface index, SiloIndexManager siloIndexManager,
                                              IIndexableGrain updatedGrain, Immutable <IMemberUpdate> update,
                                              IndexMetaData idxMetaData, SiloAddress siloAddress = null)
 {
     if (index is IActiveHashIndexPartitionedPerSilo)
     {
         var bucketInCurrentSilo = siloIndexManager.GetGrainService <IActiveHashIndexPartitionedPerSiloBucket>(
             GetAHashIndexPartitionedPerSiloGrainReference(siloIndexManager,
                                                           IndexUtils.GetIndexNameFromIndexGrain((IAddressable)index), index.GetType().GetGenericArguments()[1],
                                                           siloAddress
                                                           ));
         return(bucketInCurrentSilo.DirectApplyIndexUpdate(updatedGrain, update, idxMetaData.IsUniqueIndex, idxMetaData /*, siloAddress*/));
     }
     return(index.DirectApplyIndexUpdate(updatedGrain, update, idxMetaData.IsUniqueIndex, idxMetaData, siloAddress));
 }
        public async Task <BookInventoryApplication> AcquireInventory(Immutable <long> orderId, Immutable <int> amount)
        {
            var bookId = this.GetPrimaryKeyLong();

            using (
                var connection =
                    new SqlConnection(ConfigurationManager.ConnectionStrings["BookInventory"].ConnectionString))
            {
                await connection.OpenAsync();

                using (var transaction = connection.BeginTransaction())
                {
                    var remainInventory =
                        await connection.QueryFirstOrDefaultAsync <decimal>(
                            "SELECT [Inventory] FROM [BookInventory] WHERE [BookId]=@Id", new { Id = bookId }, transaction);

                    if (remainInventory < amount.Value)
                    {
                        throw new NoEnoughInventoryException(
                                  $"No enough book inventory, current is {remainInventory}, need {amount.Value}");
                    }

                    if (await connection.ExecuteAsync(
                            "UPDATE [BookInventory] SET [Inventory]=[Inventory]-@Inventory WHERE [BookId]=@Id",
                            new { Inventory = amount.Value, Id = bookId }, transaction) != 1)
                    {
                        throw new DbOperationFailedException();
                    }

                    var newApplication = new BookInventoryApplication
                    {
                        OrderId = orderId.Value,
                        BookId  = bookId,
                        Amount  = amount.Value,
                        Status  = (int)BookInventoryApplicationStatus.Granted
                    };

                    await connection.ExecuteAsync(
                        "INSERT INTO [BookInventoryApplication] ([OrderId], [BookId], [Amount], [Status]) VALUES " +
                        "(@OrderId, @BookId, @Amount, @Status)",
                        newApplication
                        , transaction);

                    transaction.Commit();
                    return(newApplication);
                }
            }
        }
        public async Task SerializeImmutableBigInteger_Success()
        {
            var yamlSerializer = new YamlSerializer($"{Default}");

            var sourceString = string.Join(string.Empty, Enumerable.Repeat("1234567890", 10));

            var source = new Immutable <BigInteger>(BigInteger.Parse(sourceString));

            var expected = _encoding.GetBytes($@"
property: {sourceString}
".TrimStart());

            var actual = await yamlSerializer.Serialize(source);

            Assert.Equal(expected, actual);
        }
Beispiel #13
0
        public Task AddAllToQueue(Immutable <List <IndexWorkflowRecord> > workflowRecords)
        {
            List <IndexWorkflowRecord> newWorkflows = workflowRecords.Value;

            foreach (IndexWorkflowRecord newWorkflow in newWorkflows)
            {
                AddToQueueNonPersistent(newWorkflow);
            }

            InitiateWorkerThread();
            if (IsFaultTolerant)
            {
                return(PersistState());
            }
            return(TaskDone.Done);
        }
        public void Test_Protobuf_Serialization_Round_Trip()
        {
            var testClass = new Immutable <TestClassMember>();

            testClass = testClass.Modify(x => x.Member = 1);

            var stream = new MemoryStream();

            Serializer.Serialize(stream, testClass);

            stream.Seek(0, SeekOrigin.Begin);
            var deserialized = Serializer.Deserialize <Immutable <TestClassMember> >(stream);

            deserialized.Get(x => x.Member).ShouldBe(1);
            deserialized.Get(x => x.Member2).ShouldBe(0);
        }
Beispiel #15
0
        public Task IndexAsync(NamedId <Guid> schemaId, Immutable <IndexCommand[]> updates)
        {
            foreach (var command in updates.Value)
            {
                switch (command)
                {
                case DeleteIndexEntry delete:
                    index.Writer.DeleteDocuments(new Term(MetaId, delete.DocId));
                    break;

                case UpdateIndexEntry update:
                    try
                    {
                        var values = GetValue(update.ServeAll, update.ServePublished);

                        index.Writer.UpdateBinaryDocValue(new Term(MetaId, update.DocId), MetaFor, values);
                    }
                    catch (ArgumentException)
                    {
                    }

                    break;

                case UpsertIndexEntry upsert:
                {
                    var document = new Document();

                    document.AddStringField(MetaId, upsert.DocId, Field.Store.YES);
                    document.AddStringField(MetaContentId, upsert.ContentId.ToString(), Field.Store.YES);
                    document.AddStringField(MetaSchemaId, schemaId.Id.ToString(), Field.Store.YES);
                    document.AddStringField(MetaSchemaName, schemaId.Name, Field.Store.YES);
                    document.AddBinaryDocValuesField(MetaFor, GetValue(upsert.ServeAll, upsert.ServePublished));

                    foreach (var(key, value) in upsert.Texts)
                    {
                        document.AddTextField(key, value, Field.Store.NO);
                    }

                    index.Writer.UpdateDocument(new Term(MetaId, upsert.DocId), document);

                    break;
                }
                }
            }

            return(TryCommitAsync());
        }
        async Task <Immutable <CfnResponse> > CreateSeed(CfnRequest cfnRequest, Immutable <CfnResponse> cfnResponse, ILambdaContext context)
        {
            try
            {
                var seedData = cfnRequest.ResourceProperties.SeedData;
                if (seedData == null ||
                    seedData.Count() == 0 ||
                    (seedData.Count() == 1 && string.IsNullOrEmpty(seedData.First())))
                {
                    return(cfnResponse);
                }

                var request = seedData.Select(seed =>
                {
                    return(new SaveItemRequest
                    {
                        Id = "U1",
                        Name = "This is a custom data inserted using a custom resource",
                        Key = seed
                    });
                });

                var result = await _itemService.BatchWrite(request);

                if (result != null)
                {
                    LogHandler.LogMessage(context, "Db seeding successful");
                    return(cfnResponse.Modify(r => r.Status = "SUCCESS"));
                }
                else
                {
                    LogHandler.LogMessage(context, "Db seeding failed");
                    return(cfnResponse.ToBuilder()
                           .Modify(r => r.Status = "FAILED")
                           .Modify(r => r.Reason = $"Resource: {_tableName} not found")
                           .ToImmutable());
                }
            }
            catch (Exception ex)
            {
                LogHandler.LogMessage(context, ex.StackTrace);
                return(cfnResponse.ToBuilder()
                       .Modify(r => r.Status = "FAILED")
                       .Modify(r => r.Reason = ex.Message)
                       .ToImmutable());
            }
        }
        public async Task <bool> DirectApplyIndexUpdate(IIndexableGrain g, Immutable <IMemberUpdate> iUpdate, bool isUniqueIndex, IndexMetaData idxMetaData, SiloAddress siloAddress)
        {
            IMemberUpdate      update = iUpdate.Value;
            IndexOperationType opType = update.GetOperationType();

            if (opType == IndexOperationType.Update)
            {
                int     befImgHash   = update.GetBeforeImage().GetHashCode();
                int     aftImgHash   = update.GetAfterImage().GetHashCode();
                BucketT befImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                    );
                if (befImgHash == aftImgHash)
                {
                    return(await befImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
                }
                else
                {
                    BucketT aftImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                        IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                        );
                    var    befTask = befImgBucket.DirectApplyIndexUpdate(g, new MemberUpdateOverridenOperation(iUpdate.Value, IndexOperationType.Delete).AsImmutable <IMemberUpdate>(), isUniqueIndex, idxMetaData);
                    var    aftTask = aftImgBucket.DirectApplyIndexUpdate(g, new MemberUpdateOverridenOperation(iUpdate.Value, IndexOperationType.Insert).AsImmutable <IMemberUpdate>(), isUniqueIndex, idxMetaData);
                    bool[] results = await Task.WhenAll(befTask, aftTask);

                    return(results[0] && results[1]);
                }
            }
            else if (opType == IndexOperationType.Insert)
            {
                int     aftImgHash   = update.GetAfterImage().GetHashCode();
                BucketT aftImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + aftImgHash
                    );
                return(await aftImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
            }
            else if (opType == IndexOperationType.Delete)
            {
                int     befImgHash   = update.GetBeforeImage().GetHashCode();
                BucketT befImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                    );
                return(await befImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
            }
            return(true);
        }
Beispiel #18
0
        private async Task <Immutable <byte[]> > Query <TRessourceType>(Immutable <QueryDefinition> queryDef)
        {
            try {
                var ret = await GrainFactory.GetGrain <IDistributedHashTable <Guid, TRessourceType> >(0).Query(queryDef);

                IFormatter formatter = new BinaryFormatter();
                var        stream    = new MemoryStream(5000000);
                formatter.Serialize(stream, ret.Value);
                stream.Close();

                Console.WriteLine("Returning query's result");
                return(stream.GetBuffer().AsImmutable());
            }
            catch (Exception e) {
                throw new Exception(e.Message);
            }
        }
Beispiel #19
0
            public void ShouldReturnImmutableObject_WhenObjectIsArray()
            {
                // Arrange
                var value = new SimpleTestClass[3]
                {
                    new SimpleTestClass(),
                    new SimpleTestClass(),
                    new SimpleTestClass()
                };
                var immutable = new Immutable <SimpleTestClass[]>(value);

                // Act
                var result = immutable[0];

                // Assert
                result.Should().BeOfType <Immutable <SimpleTestClass> >();
            }
Beispiel #20
0
            public void ShouldThrowException_WhenObjectIsArrayAndIndexIsOutOfBounds()
            {
                // Arrange
                var value = new SimpleTestClass[3]
                {
                    new SimpleTestClass(),
                    new SimpleTestClass(),
                    new SimpleTestClass()
                };
                var immutable = new Immutable <SimpleTestClass[]>(value);

                // Act
                Action result = () => _ = immutable[4];

                // Assert
                result.Should().Throw <IndexOutOfRangeException>().WithMessage("Index was out of range. Must be non-negative and less than the size of the collection.");
            }
Beispiel #21
0
 public Task PingImmutableArray(Immutable <byte[]> data, long nextGrain, bool nextGrainIsRemote)
 {
     if (nextGrain > 0)
     {
         if (nextGrainIsRemote)
         {
             return(GrainFactory.GetGrain <IReentrantStressTestGrain>(nextGrain)
                    .PingImmutableArray(data, -1, false));
         }
         else
         {
             return(GrainFactory.GetGrain <IReentrantLocalStressTestGrain>(nextGrain)
                    .PingImmutableArray(data, -1, false));
         }
     }
     return(TaskDone.Done);
 }
Beispiel #22
0
        private async Task <IGrainReminder> CreateNewOrderFO(Immutable <long> userId, Immutable <long> bookId, Immutable <int> amount, long orderId)
        {
            var reminder = await RegisterOrUpdateReminder(GetCreateOrderReminderName(), CheckDuration, CheckDuration);

            using (var connection = GetConnection())
            {
                await connection.ExecuteAsync("INSERT INTO [Order] ([Id], [UserId], [BookId], [Amount], [Status]) VALUES " +
                                              "(@Id, @UserId, @BookId, @Amount, @Status)", new OrderFO
                {
                    Amount = amount.Value,
                    BookId = bookId.Value,
                    Id     = orderId,
                    UserId = userId.Value,
                    Status = OrderStatus.Created
                });
            }
            return(reminder);
        }
        public Task Dispatch(Immutable <EventGridEvent[]> events)
        {
            var eventGridEvents = events.Value;

            if (eventGridEvents?.Length == 0)
            {
                return(Task.CompletedTask);
            }

            var tasks = new List <Task>();

            foreach (var @event in eventGridEvents)
            {
                tasks.Add(TryDispatch(@event));
            }

            return(Task.WhenAll(tasks));
        }
        public Task Initialize(Immutable<IQueueAdapter> qAdapter)
        {
            if (qAdapter.Value == null) throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null");

            Log(ErrorCode.PersistentStreamPullingManager_02, "Init.");

            // Remove cast once we cleanup
            queueAdapter = qAdapter.Value;

            var meAsQueueBalanceListener = this.AsReference<IStreamQueueBalanceListener>();
            queueBalancer.SubscribeToQueueDistributionChangeEvents(meAsQueueBalanceListener);

            List<QueueId> myQueues = queueBalancer.GetMyQueues().ToList();
            Log(ErrorCode.PersistentStreamPullingManager_03, String.Format("Initialize: I am now responsible for {0} queues: {1}.", myQueues.Count, PrintQueues(myQueues)));

            managerState = PersistentStreamProviderState.Initialized;
            return TaskDone.Done;
        }
Beispiel #25
0
        public Task SendPacket(uint packetId, Immutable <byte[]> data)
        {
            var packet = new UncompressedPacket
            {
                PacketId = packetId,
                Data     = new ArraySegment <byte>(data.Value)
            };

            if (_subsManager.Count == 0)
            {
                DeactivateOnIdle();
            }
            else
            {
                _subsManager.Notify(n => n.ReceivePacket(packet));
            }
            return(Task.CompletedTask);
        }
        public Task Set(Immutable <TKey> key, Immutable <TValue> value)
        {
            Task Set()
            {
                if (State.ContainsKey(key.Value))
                {
                    State[key.Value] = value.Value;
                }
                else
                {
                    State.Add(key.Value, value.Value);
                }
                return(Task.CompletedTask);
            }

            CommitChanges();
            return(SerialExecutor.AddNext(Set));
        }
Beispiel #27
0
        public Task OnEventAsync(Immutable <IEventSubscription> subscription, Immutable <StoredEvent> storedEvent)
        {
            if (subscription.Value != currentSubscription)
            {
                return(TaskHelper.Done);
            }

            return(DoAndUpdateStateAsync(async() =>
            {
                var @event = ParseKnownEvent(storedEvent.Value);

                if (@event != null)
                {
                    await DispatchConsumerAsync(@event);
                }

                State = State.Handled(storedEvent.Value.EventPosition);
            }));
        }
        /// <summary>
        /// This method assumes that a set of changes is applied to the indexes, and then it replaces the current before-images
        /// with after-images produced by the update.
        /// </summary>
        /// <param name="updates">the member updates that were successfully applied to the current indexes</param>
        protected void UpdateBeforeImages(IDictionary <string, IMemberUpdate> updates)
        {
            IDictionary <string, object> befImgs = new Dictionary <string, object>(this._beforeImages.Value);

            foreach (KeyValuePair <string, IMemberUpdate> updt in updates)
            {
                var indexID = updt.Key;
                var opType  = updt.Value.OperationType;
                if (opType == IndexOperationType.Update || opType == IndexOperationType.Insert)
                {
                    befImgs[indexID] = _grainIndexes[indexID].UpdateGenerator.ExtractIndexImage(this.Properties);
                }
                else if (opType == IndexOperationType.Delete)
                {
                    befImgs[indexID] = null;
                }
            }
            this._beforeImages = befImgs.AsImmutable();
        }
        /// <summary>
        /// Take responsibility for a new queues that was assigned to me via a new range.
        /// We first store the new queue in our internal data structure, try to initialize it and start a pumping timer.
        /// ERROR HANDLING:
        ///     The resposibility to handle initializatoion and shutdown failures is inside the INewQueueAdapterReceiver code.
        ///     The agent will call Initialize once and log an error. It will not call initiliaze again.
        ///     The receiver itself may attempt later to recover from this error and do initialization again.
        ///     The agent will assume initialization has succeeded and will subsequently start calling pumping receive.
        ///     Same applies to shutdown.
        /// </summary>
        /// <param name="qAdapter"></param>
        /// <returns></returns>
        public async Task Initialize(Immutable <IQueueAdapter> qAdapter)
        {
            if (qAdapter.Value == null)
            {
                throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null");
            }

            logger.Info((int)ErrorCode.PersistentStreamPullingAgent_02, "Init of {0} {1} on silo {2} for queue {3}.",
                        this.GetType().Name, this.GrainId.ToDetailedString(), base.Silo, QueueId.ToStringWithHashCode());

            // Remove cast once we cleanup
            queueAdapter = qAdapter.Value;

            try
            {
                receiver = queueAdapter.CreateReceiver(QueueId);
            }
            catch (Exception exc)
            {
                logger.Error((int)ErrorCode.PersistentStreamPullingAgent_02, String.Format("Exception while calling INewQueueAdapter.CreateNewReceiver."), exc);
                return;
            }

            try
            {
                var task = OrleansTaskExtentions.SafeExecute(() => receiver.Initialize(initQueueTimeout));
                task = task.LogException(logger, ErrorCode.PersistentStreamPullingAgent_03, String.Format("QueueAdapterReceiver {0} failed to Initialize.", QueueId.ToStringWithHashCode()));
                await task;
            }
            catch (Exception)
            {
                // Just ignore this exception and proceed as if Initialize has succeeded.
                // We already logged individual exceptions for individual calls to Initialize. No need to log again.
            }
            // Setup a reader for a new receiver.
            // Even if the receiver failed to initialise, treat it as OK and start pumping it. It's receiver responsibility to retry initialization.
            var randomTimerOffset = safeRandom.NextTimeSpan(queueGetPeriod);

            timer = providerRuntime.RegisterTimer(AsyncTimerCallback, QueueId, randomTimerOffset, queueGetPeriod);

            logger.Info((int)ErrorCode.PersistentStreamPullingAgent_04, "Taking queue {0} under my responsibility.", QueueId.ToStringWithHashCode());
        }
        /// <summary>
        /// This method checks the list of cached indexes, and if
        /// any index does not have a before-image, it will create
        /// one for it. As before-images are stored as an immutable
        /// field, a new map is created in this process.
        ///
        /// This method is called on activation of the grain, and when the
        /// UpdateIndexes method detects an inconsistency between the indexes
        /// in the index handler and the cached indexes of the current grain.
        /// </summary>
        private void AddMissingBeforeImages()
        {
            IDictionary <string, Tuple <object, object, object> > iUpdateGens = _iUpdateGens;
            IDictionary <string, object> oldBefImgs = _beforeImages.Value;
            IDictionary <string, object> newBefImgs = new Dictionary <string, object>();

            foreach (KeyValuePair <string, Tuple <object, object, object> > idxOp in iUpdateGens)
            {
                var indexID = idxOp.Key;
                if (!oldBefImgs.ContainsKey(indexID))
                {
                    newBefImgs.Add(indexID, ((IIndexUpdateGenerator)idxOp.Value.Item3).ExtractIndexImage(Properties));
                }
                else
                {
                    newBefImgs.Add(indexID, oldBefImgs[indexID]);
                }
            }
            _beforeImages = newBefImgs.AsImmutable();
        }
        public Task <StreamSequenceToken> DeliverBatch(GuidId subscriptionId, Immutable <IBatchContainer> batch, StreamSequenceToken handshakeToken)
        {
            if (logger.IsVerbose3)
            {
                logger.Verbose3("DeliverBatch {0} for subscription {1}", batch.Value, subscriptionId);
            }

            IStreamSubscriptionHandle observer;

            if (allStreamObservers.TryGetValue(subscriptionId, out observer))
            {
                return(observer.DeliverBatch(batch.Value, handshakeToken));
            }

            logger.Warn((int)(ErrorCode.StreamProvider_NoStreamForBatch), "{0} got an item for subscription {1}, but I don't have any subscriber for that stream. Dropping on the floor.",
                        providerRuntime.ExecutingEntityIdentity(), subscriptionId);
            // We got an item when we don't think we're the subscriber. This is a normal race condition.
            // We can drop the item on the floor, or pass it to the rendezvous, or ...
            return(Task.FromResult(default(StreamSequenceToken)));
        }
Beispiel #32
0
        public Task <StreamSequenceToken> DeliverItem(GuidId subscriptionId, Immutable <object> item, StreamSequenceToken currentToken, StreamSequenceToken prevToken)
        {
            if (logger.IsVerbose3)
            {
                logger.Verbose3("DeliverItem {0} for subscription {1}", item.Value, subscriptionId);
            }

            IStreamSubscriptionHandle observer;

            if (allStreamObservers.TryGetValue(subscriptionId, out observer))
            {
                return(observer.DeliverItem(item.Value, currentToken, prevToken));
            }

            logger.Warn((int)(ErrorCode.StreamProvider_NoStreamForItem), "{0} got an item for subscription {1}, but I don't have any subscriber for that stream. Dropping on the floor.",
                        providerRuntime.ExecutingEntityIdentity(), subscriptionId);
            // We got an item when we don't think we're the subscriber. This is a normal race condition.
            // We can drop the item on the floor, or pass it to the rendezvous, or ...
            return(Task.FromResult <StreamSequenceToken>(null));
        }
Beispiel #33
0
        public override string ToString()
        {
            var b = new StringBuilder("Validation Item (")
                    .Append(ItemId)
                    .Append(") ")
                    .Append(Valid ? "[Valid]" : "[Invalid]")
                    .Append(" {")
                    .Append(string.Join(",", Messages ?? Immutable.ReadOnlyList <string>()))
                    .Append(" }");

            if (CollectionUtil.IsNotNullOrEmpty(NestedResults))
            {
                b.Append(" Nested (").Append(NestedResults.Count).Append(") [")
                .Append(Environment.NewLine)
                .Append(string.Join(Environment.NewLine, NestedResults ?? Immutable.ReadOnlyList <IValidationResult>()))
                .Append(Environment.NewLine)
                .Append("]");
            }
            return(b.ToString());
        }
        async Task <Immutable <CfnResponse> > DeleteTable(CfnRequest cfnRequest, Immutable <CfnResponse> cfnResponse, ILambdaContext context)
        {
            try
            {
                await _itemService.DeleteTable();

                await _userService.DeleteTable();

                LogHandler.LogMessage(context, $"Request {cfnRequest.RequestType} executed Successfully");
                return(cfnResponse.Modify(r => r.Status = "SUCCESS"));
            }
            catch (Exception ex)
            {
                LogHandler.LogMessage(context, $"Message: {ex.Message} /Trace: {ex.StackTrace}");
                return(cfnResponse.ToBuilder()
                       .Modify(r => r.Status = "FAILED")
                       .Modify(r => r.Reason = ex.Message)
                       .ToImmutable());
            }
        }
        /// <summary>
        /// Upon activation, the list of index update generators
        /// is retrieved from the index handler. It is cached in
        /// this grain for use in creating before-images, and also
        /// for later calls to UpdateIndexes.
        ///
        /// Then, the before-images are created and stored in memory.
        /// </summary>
        public override Task OnActivateAsync()
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("Activating indexable grain {0} of type {1} in silo {2}.", Orleans.GrainExtensions.GetGrainId(this), GetIIndexableGrainTypes()[0], RuntimeAddress);
            }
            //load indexes
            _iUpdateGens = IndexHandler.GetIndexes(GetIIndexableGrainTypes()[0]);

            //initialized _isThereAnyUniqueIndex field
            InitUniqueIndexCheck();

            //Initialize before images
            _beforeImages = new Dictionary <string, object>().AsImmutable <IDictionary <string, object> >();
            AddMissingBeforeImages();

            //insert the current grain to the active indexes defined on this grain
            //and at the same time call OnActivateAsync of the base class
            return(Task.WhenAll(InsertIntoActiveIndexes(), base.OnActivateAsync()));
        }
        /// <summary>
        /// This method assumes that a set of changes is applied to the
        /// indexes, and then it replaces the current before-images with
        /// after-images produced by the update.
        /// </summary>
        /// <param name="updates">the member updates that were successfully
        /// applied to the current indexes</param>
        protected void UpdateBeforeImages(IDictionary <string, IMemberUpdate> updates)
        {
            IDictionary <string, Tuple <object, object, object> > iUpdateGens = _iUpdateGens;
            IDictionary <string, object> befImgs = new Dictionary <string, object>(_beforeImages.Value);

            foreach (KeyValuePair <string, IMemberUpdate> updt in updates)
            {
                var indexID = updt.Key;
                var opType  = updt.Value.GetOperationType();
                if (opType == IndexOperationType.Update || opType == IndexOperationType.Insert)
                {
                    befImgs[indexID] = ((IIndexUpdateGenerator)iUpdateGens[indexID].Item3).ExtractIndexImage(Properties);
                }
                else if (opType == IndexOperationType.Delete)
                {
                    befImgs[indexID] = null;
                }
            }
            _beforeImages = befImgs.AsImmutable();
        }
 public TestClass()
 {
     Data = new Immutable<TestClassMember>();
 }
Beispiel #38
0
 public async Task<StreamHandshakeToken> DeliverItem(GuidId subscriptionId, Immutable<object> item, StreamSequenceToken currentToken, StreamHandshakeToken handshakeToken)
 {
     await handler(item.Value);
     return null;
 }
        public void Test_That_Modify_Can_Alter_Converted_Nullables()
        {
            var testClass = new Immutable<TestNullableClass>();
            decimal? testDecimal = null;

            testClass = testClass.Modify(x => x.Nullable, testDecimal);

            Assert.Null(testClass.Get(x => x.Nullable));
        }
        public void Immutable_Microbenchmark()
        {
            var stopwatch = new Stopwatch();
            var testClass = new TestClass();
            var testClassImmutable = new Immutable<TestClass>();

            stopwatch.Start();
            for(var i = 0; i < 100000; i++)
            {
                testClass.Test = i;
            }
            stopwatch.Stop();

            var setterTime = stopwatch.ElapsedMilliseconds;

            stopwatch.Reset();
            stopwatch.Start();
            for(var i = 0; i < 100000; i++)
            {
               testClassImmutable.Modify(x => x.Test, i);
            }
            stopwatch.Stop();

            var immutableTime = stopwatch.ElapsedMilliseconds;
        }
 /// <summary>
 /// Take responsibility for a new queues that was assigned to me via a new range.
 /// We first store the new queue in our internal data structure, try to initialize it and start a pumping timer.
 /// ERROR HANDLING:
 ///     The resposibility to handle initializatoion and shutdown failures is inside the INewQueueAdapterReceiver code.
 ///     The agent will call Initialize once and log an error. It will not call initiliaze again.
 ///     The receiver itself may attempt later to recover from this error and do initialization again. 
 ///     The agent will assume initialization has succeeded and will subsequently start calling pumping receive.
 ///     Same applies to shutdown.
 /// </summary>
 /// <param name="qAdapter"></param>
 /// <param name="queueAdapterCache"></param>
 /// <param name="failureHandler"></param>
 /// <returns></returns>
 public Task Initialize(Immutable<IQueueAdapter> qAdapter, Immutable<IQueueAdapterCache> queueAdapterCache, Immutable<IStreamFailureHandler> failureHandler)
 {
     if (qAdapter.Value == null) throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null");
     if (failureHandler.Value == null) throw new ArgumentNullException("failureHandler", "Init: streamDeliveryFailureHandler should not be null");
     return OrleansTaskExtentions.WrapInTask(() => InitializeInternal(qAdapter.Value, queueAdapterCache.Value, failureHandler.Value));
 }
Beispiel #42
0
 public Task PingImmutableArray(Immutable<byte[]> data, long nextGrain, bool nextGrainIsRemote)
 {
     if (nextGrain > 0)
     {
         if (nextGrainIsRemote)
         {
             return GrainFactory.GetGrain<IReentrantStressTestGrain>(nextGrain)
                 .PingImmutableArray(data, -1, false);
         }
         else
         {
             return GrainFactory.GetGrain<IReentrantLocalStressTestGrain>(nextGrain)
                 .PingImmutableArray(data, -1, false);
         }
     }
     return TaskDone.Done;
 }
            internal Task DeliverItem(StreamId streamId, object item, bool fireAndForgetDelivery)
            {
                var tasks = fireAndForgetDelivery ? null : new List<Task>();
                var immutableItem = new Immutable<object>(item);
                foreach (KeyValuePair<GuidId, Tuple<IStreamConsumerExtension, IStreamFilterPredicateWrapper>> subscriptionKvp in consumers)
                {
                    IStreamConsumerExtension remoteConsumer = subscriptionKvp.Value.Item1;

                    // Apply filter(s) to see if we should forward this item to this consumer
                    IStreamFilterPredicateWrapper filter = subscriptionKvp.Value.Item2;
                    if (filter != null)
                    {
                        if (!filter.ShouldReceive(streamId, filter.FilterData, item))
                            continue;
                    }

                    Task task = remoteConsumer.DeliverItem(subscriptionKvp.Key, immutableItem, null, null);
                    if (fireAndForgetDelivery) task.Ignore();
                    else tasks.Add(task);
                }
                // If there's no subscriber, presumably we just drop the item on the floor
                return fireAndForgetDelivery ? TaskDone.Done : Task.WhenAll(tasks);
            }
Beispiel #44
0
 public Task PingImmutableDictionary(Immutable<Dictionary<int, string>> data, long nextGrain,
     bool nextGrainIsRemote)
 {
     if (nextGrain > 0)
     {
         if (nextGrainIsRemote)
         {
             return GrainFactory.GetGrain<IReentrantStressTestGrain>(nextGrain)
                 .PingImmutableDictionary(data, -1, false);
         }
         else
         {
             return GrainFactory.GetGrain<IReentrantLocalStressTestGrain>(nextGrain)
                 .PingImmutableDictionary(data, -1, false);
         }
     }
     return TaskDone.Done;
 }
        public Task Initialize(Immutable<IQueueAdapter> qAdapter)
        {
            if (qAdapter.Value == null) throw new ArgumentNullException("qAdapter", "Init: queueAdapter should not be null");

            logger.Info((int)ErrorCode.PersistentStreamPullingManager_02, "Init.");

            // Remove cast once we cleanup
            queueAdapter = qAdapter.Value;

            var meAsQueueBalanceListener = this.AsReference<IStreamQueueBalanceListener>();
            queueBalancer.SubscribeToQueueDistributionChangeEvents(meAsQueueBalanceListener);

            List<QueueId> myQueues = queueBalancer.GetMyQueues().ToList();
            logger.Info((int)ErrorCode.PersistentStreamPullingManager_03, PrintMyState(myQueues));

            return AddNewQueues(myQueues, true);
        }
        public void Test_That_ToBuilder_Returns_New_Instance()
        {
            var testClass = new Immutable<TestClass>();
            var builder = testClass.ToBuilder();

            Assert.NotSame(testClass, builder);
        }
        public void Test_That_Modifying_Nested_Returns_Modifications()
        {
            var testClass = new Immutable<TestClass>();
            var newTestClass = testClass.Modify(x => x.Data, 
                testClass.Get(x => x.Data)
                .Modify(x => x.Member, 2)
            );

            Assert.Equal(newTestClass.Get(x => x.Data.Get(y => y.Member)), 2);
        }
        public void Test_Modify_Nested_With_Implicit_Conversion()
        {
            var testClass = new Immutable<TestClass>();
            var newTestClass = testClass.Modify(x => x.Data,
                testClass.Get(x => x.Data)
                .Modify(x => x.Member, 2.0M)
            );

            Assert.Equal(newTestClass.Get(x => x.Data.Get(y => y.Member)), 2);
        }