private async Task <List <ResultData> > GenerateInsertConflicts(ILogger logger, Uri collectionUri, string test)
        {
            List <ResultData> results = new List <ResultData>();

            try
            {
                bool isConflicts = false;

                logger.LogInformation($"{test}");

                while (!isConflicts)
                {
                    List <Task <SampleCustomer> > tasks = new List <Task <SampleCustomer> >();

                    SampleCustomer customer = customerGenerator.Generate();

                    foreach (DocumentClient client in clients)
                    {
                        tasks.Add(InsertItemAsync(logger, client, collectionUri, customer));
                    }

                    SampleCustomer[] insertedItems = await Task.WhenAll(tasks);

                    isConflicts = IsConflicts(logger, insertedItems);
                    if (isConflicts)
                    {
                        foreach (var conflict in insertedItems)
                        {
                            try
                            {
                                results.Add(new ResultData()
                                {
                                    Test = $"Generated Conflict in container {collectionUri} - Name: {conflict.Name}, City: {conflict.City}, UserDefId: {conflict.UserDefinedId}, Region: {conflict.Region}"
                                });
                            }
                            catch (Exception ex)
                            {
                                logger.LogError(ex, "test");
                            }
                        }
                    }
                }
            }
            catch (DocumentClientException dcx)
            {
                logger.LogInformation(dcx.Message);
            }

            return(results);
        }
        private async Task <List <ResultData> > WriteBenchmark(ILogger logger, DocumentClient client, string distance)
        {
            List <ResultData> results = new List <ResultData>();

            Stopwatch stopwatch = new Stopwatch();
            int       i         = 0;
            int       total     = 100;
            long      lt        = 0;
            double    ru        = 0;

            //Write tests for account with Eventual consistency
            string region      = Helpers.ParseEndpoint(client.WriteEndpoint);
            string consistency = client.ConsistencyLevel.ToString();

            logger.LogInformation($"Test {total} writes account in {region} with {consistency} consistency level, and replica {distance} away.");

            for (i = 0; i < total; i++)
            {
                SampleCustomer customer = customerGenerator.Generate();
                stopwatch.Start();
                ResourceResponse <Document> response = await client.CreateDocumentAsync(containerUri, customer);

                stopwatch.Stop();
                logger.LogInformation($"Write: Item {i} of {total}, Region: {region}, Latency: {stopwatch.ElapsedMilliseconds} ms, Request Charge: {response.RequestCharge} RUs");
                lt += stopwatch.ElapsedMilliseconds;
                ru += response.RequestCharge;
                stopwatch.Reset();
            }
            results.Add(new ResultData
            {
                Test       = $"Test with {consistency} Consistency",
                AvgLatency = (lt / total).ToString(),
                AvgRU      = Math.Round(ru / total).ToString()
            });

            logger.LogInformation("Summary");
            logger.LogInformation($"Test 100 writes against account in {region} with {consistency} consistency level, with replica {distance} away");

            logger.LogInformation($"Average Latency:\t{(lt / total)} ms");
            logger.LogInformation($"Average Request Units:\t{Math.Round(ru / total)} RUs");

            return(results);
        }
Пример #3
0
        private async Task <List <ResultData> > WriteBenchmarkCustomSync(ILogger logger, DocumentClient writeClient, DocumentClient readClient)
        {
            List <ResultData> results   = new List <ResultData>();
            Stopwatch         stopwatch = new Stopwatch();

            int    i     = 0;
            int    total = 100;
            long   lt    = 0;
            double ru    = 0;
            long   ltAgg = 0;
            double ruAgg = 0;

            string writeRegion = Helpers.ParseEndpoint(writeClient.WriteEndpoint);
            string readRegion  = Helpers.ParseEndpoint(readClient.ReadEndpoint);
            string consistency = writeClient.ConsistencyLevel.ToString();

            logger.LogInformation($"Test {total} writes in {writeRegion} with {consistency} consistency between all replicas except {readRegion} with Strong consistency.");

            PartitionKey partitionKeyValue = new PartitionKey(PartitionKeyValue);

            for (i = 0; i < total; i++)
            {
                SampleCustomer customer = customerGenerator.Generate();

                stopwatch.Start();
                ResourceResponse <Document> writeResponse = await writeClient.CreateDocumentAsync(containerUri, customer);

                stopwatch.Stop();
                lt += stopwatch.ElapsedMilliseconds;
                ru += writeResponse.RequestCharge;
                stopwatch.Reset();

                stopwatch.Start();
                ResourceResponse <Document> readResponse = await readClient.ReadDocumentAsync(writeResponse.Resource.SelfLink,
                                                                                              new RequestOptions { PartitionKey = partitionKeyValue, SessionToken = writeResponse.SessionToken });

                stopwatch.Stop();
                lt += stopwatch.ElapsedMilliseconds;
                ru += readResponse.RequestCharge;
                stopwatch.Reset();
                logger.LogInformation($"Write/Read: Item {i} of {total}, Region: {writeRegion}, Latency: {lt} ms, Request Charge: {ru} RUs");

                ltAgg += lt;
                ruAgg += ru;
                lt     = 0;
                ru     = 0;
            }
            results.Add(new ResultData
            {
                Test       = $"Test {total} writes in {writeRegion} with {consistency} consistency between all replicas except {readRegion} with Strong consistency",
                AvgLatency = (ltAgg / total).ToString(),
                AvgRU      = Math.Round(ruAgg / total).ToString()
            });

            logger.LogInformation("Test Summary");
            logger.LogInformation($"Test {total} writes in {writeRegion} with {consistency} consistency between all replicas except {readRegion} with Strong consistency");

            logger.LogInformation($"Average Latency:\t{(ltAgg / total)} ms");
            logger.LogInformation($"Average Request Units:\t{Math.Round(ruAgg / total)} RUs");

            return(results);
        }
        private async Task <SampleCustomer> UpdateItemAsync(ILogger logger, DocumentClient client, Uri collectionUri, SampleCustomer item)
        {
            //DeepCopy the item
            item = Helpers.Clone(item);

            //Make a change to the item to update.
            item.Region        = Helpers.ParseEndpoint(client.WriteEndpoint);
            item.UserDefinedId = Helpers.RandomNext(0, 1000);

            logger.LogInformation($"Update - Name: {item.Name}, City: {item.City}, UserDefId: {item.UserDefinedId}, Region: {item.Region}");

            try
            {
                var response = await client.ReplaceDocumentAsync(item.SelfLink, item, new RequestOptions
                {
                    AccessCondition = new AccessCondition
                    {
                        Type      = AccessConditionType.IfMatch,
                        Condition = item.ETag
                    }
                });

                return((SampleCustomer)(dynamic)response.Resource);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.PreconditionFailed || ex.StatusCode == HttpStatusCode.NotFound)
                {
                    //No conflict is induced.
                    return(null);
                }
                throw;
            }
        }
        private async Task <List <ResultData> > GenerateUpdateConflicts(ILogger logger, Uri collectionUri, string test)
        {
            List <ResultData> results = new List <ResultData>();

            try
            {
                bool isConflicts = false;

                logger.LogInformation($"{test}");

                logger.LogInformation($"Inserting an item to create an update conflict on.");

                //Generate a new customer, set the region property
                SampleCustomer customer = customerGenerator.Generate();

                SampleCustomer insertedItem = await InsertItemAsync(logger, clients[0], collectionUri, customer);

                logger.LogInformation($"Wait 2 seconds to allow item to replicate.");
                await Task.Delay(2000);

                RequestOptions requestOptions = new RequestOptions
                {
                    PartitionKey = new PartitionKey(PartitionKeyValue)
                };

                while (!isConflicts)
                {
                    IList <Task <SampleCustomer> > tasks = new List <Task <SampleCustomer> >();

                    SampleCustomer item = await clients[0].ReadDocumentAsync <SampleCustomer>(insertedItem.SelfLink, requestOptions);
                    logger.LogInformation($"Original - Name: {item.Name}, City: {item.City}, UserDefId: {item.UserDefinedId}, Region: {item.Region}");

                    foreach (DocumentClient client in clients)
                    {
                        tasks.Add(UpdateItemAsync(logger, client, collectionUri, item));
                    }

                    SampleCustomer[] updatedItems = await Task.WhenAll(tasks);

                    //Delay to allow data to replicate
                    await Task.Delay(2000);

                    isConflicts = IsConflicts(logger, updatedItems);

                    if (isConflicts)
                    {
                        foreach (var conflict in updatedItems)
                        {
                            try
                            {
                                results.Add(new ResultData()
                                {
                                    Test = $"Generated Conflict in container {collectionUri} - Name: {conflict.Name}, City: {conflict.City}, UserDefId: {conflict.UserDefinedId}, Region: {conflict.Region}"
                                });
                            }
                            catch (Exception ex)
                            {
                                logger.LogError(ex, "test");
                            }
                        }
                    }
                }
            }
            catch (DocumentClientException dcx)
            {
                logger.LogInformation(dcx.Message);
            }

            return(results);
        }
        private async Task <SampleCustomer> InsertItemAsync(ILogger logger, DocumentClient client, Uri collectionUri, SampleCustomer item)
        {
            //DeepCopy the item
            item = Helpers.Clone(item);

            //Update UserDefinedId for each item to random number for Conflict Resolution
            item.UserDefinedId = Helpers.RandomNext(0, 1000);
            //Update the write region to the client regions so we know which client wrote the item
            item.Region = Helpers.ParseEndpoint(client.WriteEndpoint);

            logger.LogInformation($"Attempting insert - Name: {item.Name}, City: {item.City}, UserDefId: {item.UserDefinedId}, Region: {item.Region}");

            try
            {
                var response = await client.CreateDocumentAsync(collectionUri, item);

                return((SampleCustomer)(dynamic)response.Resource);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == System.Net.HttpStatusCode.Conflict)
                {
                    //Item has already replicated so return null
                    return(null);
                }
                if (ex.StatusCode == System.Net.HttpStatusCode.Gone)
                {
                    return(await InsertItemAsync(logger, client, collectionUri, item));
                }

                throw;
            }
        }
 //Deep copy Document object
 public static SampleCustomer Clone(SampleCustomer source)
 {
     return(JsonConvert.DeserializeObject <SampleCustomer>(JsonConvert.SerializeObject(source)));
 }