Beispiel #1
0
 private void SetBackupStatus(BackupStatus backupStatus)
 {
     using (var writer = storage.CreateWriter())
     {
         writer.SaveBackupStatus(backupStatus);
     }
 }
Beispiel #2
0
        public HttpResponseMessage Delete(string groupName, string counterName)
        {
            var verificationResult = VerifyGroupAndCounterName(groupName, counterName);

            if (verificationResult != null)
            {
                return(verificationResult);
            }

            using (var writer = CounterStorage.CreateWriter())
            {
                writer.Delete(groupName, counterName);
                writer.Commit();
            }

            CounterStorage.MetricsCounters.ClientRequests.Mark();
            CounterStorage.MetricsCounters.Deletes.Mark();
            CounterStorage.Publisher.RaiseNotification(new ChangeNotification
            {
                GroupName   = groupName,
                CounterName = counterName,
                Action      = CounterChangeAction.Delete,
                Delta       = 0,
                Total       = 0
            });

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Beispiel #3
0
 private void StoreCounterChange(long change, CounterStorage counterStorage)
 {
     using (var writer = counterStorage.CreateWriter())
     {
         writer.Store("Bar", "Foo", change);
         writer.Commit();
     }
 }
 private static void SetupCounters(CounterStorage counterStorage)
 {
     using (var writer = counterStorage.CreateWriter())
     {
         writer.Store("ga", "ca", 0);
         writer.Store("ga", "cb", 1);
         writer.Store("ga", "cc", 2);
         writer.Store("gb", "cb", 2);
         writer.Store("gc", "cc", 3);
         writer.Commit();
     }
 }
        public async Task <HttpResponseMessage> ReplicationsSave()
        {
            var newReplicationDocument = await ReadJsonObjectAsync <CountersReplicationDocument>().ConfigureAwait(false);

            using (var writer = CounterStorage.CreateWriter())
            {
                writer.UpdateReplications(newReplicationDocument);
                writer.Commit();

                return(GetEmptyMessage());
            }
        }
Beispiel #6
0
        public HttpResponseMessage PurgeTombstones()
        {
            CounterStorage.MetricsCounters.ClientRequests.Mark();

            while (true)
            {
                using (var writer = CounterStorage.CreateWriter())
                {
                    if (writer.PurgeOutdatedTombstones() == false)
                    {
                        break;
                    }

                    writer.Commit();
                }
            }

            return(GetEmptyMessage());
        }
Beispiel #7
0
        public HttpResponseMessage DeleteByGroup(string groupName)
        {
            groupName = groupName ?? string.Empty;
            var deletedCount = 0;

            while (true)
            {
                var changeNotifications = new List <ChangeNotification>();
                using (var writer = CounterStorage.CreateWriter())
                {
                    var countersDetails = writer.GetCountersDetails(groupName).Take(1024).ToList();
                    if (countersDetails.Count == 0)
                    {
                        break;
                    }

                    foreach (var c in countersDetails)
                    {
                        writer.DeleteCounterInternal(c.Group, c.Name);
                        changeNotifications.Add(new ChangeNotification
                        {
                            GroupName   = c.Group,
                            CounterName = c.Name,
                            Action      = CounterChangeAction.Delete,
                            Delta       = 0,
                            Total       = 0
                        });
                    }
                    writer.Commit();

                    deletedCount += changeNotifications.Count;
                }

                CounterStorage.MetricsCounters.ClientRequests.Mark();
                changeNotifications.ForEach(change =>
                {
                    CounterStorage.Publisher.RaiseNotification(change);
                    CounterStorage.MetricsCounters.Deletes.Mark();
                });
            }

            return(GetMessageWithObject(deletedCount));
        }
Beispiel #8
0
        public HttpResponseMessage Change(string groupName, string counterName, long delta)
        {
            var verificationResult = VerifyGroupAndCounterName(groupName, counterName);

            if (verificationResult != null)
            {
                return(verificationResult);
            }

            CounterChangeAction counterChangeAction;
            long?total = 0;

            using (var writer = CounterStorage.CreateWriter())
            {
                counterChangeAction = writer.Store(groupName, counterName, delta);
                if (delta == 0 && counterChangeAction != CounterChangeAction.Add)
                {
                    return(GetEmptyMessage());
                }

                writer.Commit();
                if (!writer.TryGetCounterTotal(groupName, counterName, out total))
                {
                    return(GetMessageWithObject(new
                    {
                        Message = $"Could not find a counter with groupName = {groupName}, counterName = {counterName}"
                    }, HttpStatusCode.NotFound));
                }
            }

            CounterStorage.MetricsCounters.ClientRequests.Mark();
            CounterStorage.Publisher.RaiseNotification(new ChangeNotification
            {
                GroupName   = groupName,
                CounterName = counterName,
                Action      = counterChangeAction,
                Delta       = delta,
                Total       = total.Value
            });

            return(GetEmptyMessage());
        }
Beispiel #9
0
        public HttpResponseMessage Reset(string groupName, string counterName)
        {
            var verificationResult = VerifyGroupAndCounterName(groupName, counterName);

            if (verificationResult != null)
            {
                return(verificationResult);
            }

            long difference = 0;

            using (var writer = CounterStorage.CreateWriter())
            {
                difference = writer.Reset(groupName, counterName);
                if (difference != 0)
                {
                    writer.Commit();
                }
            }

            if (difference != 0)
            {
                CounterStorage.MetricsCounters.ClientRequests.Mark();
                CounterStorage.MetricsCounters.Resets.Mark();
                CounterStorage.Publisher.RaiseNotification(new ChangeNotification
                {
                    GroupName   = groupName,
                    CounterName = counterName,
                    Action      = difference >= 0 ? CounterChangeAction.Increment : CounterChangeAction.Decrement,
                    Delta       = difference,
                    Total       = 0
                });
            }

            return(GetEmptyMessage());
        }
Beispiel #10
0
        public HttpResponseMessage Change(string groupName, string counterName, long delta)
        {
            var verificationResult = VerifyGroupAndCounterName(groupName, counterName);

            if (verificationResult != null)
            {
                return(verificationResult);
            }

            CounterChangeAction counterChangeAction;
            long total = 0;

            using (var writer = CounterStorage.CreateWriter())
            {
                counterChangeAction = writer.Store(groupName, counterName, delta);
                if (delta == 0 && counterChangeAction != CounterChangeAction.Add)
                {
                    return(GetEmptyMessage());
                }

                writer.Commit();
                total = writer.GetCounterTotal(groupName, counterName);
            }

            CounterStorage.MetricsCounters.ClientRequests.Mark();
            CounterStorage.Publisher.RaiseNotification(new ChangeNotification
            {
                GroupName   = groupName,
                CounterName = counterName,
                Action      = counterChangeAction,
                Delta       = delta,
                Total       = total
            });

            return(GetEmptyMessage());
        }
        public async Task <HttpResponseMessage> Post()
        {
            /*Read Current Counter Value for CounterStorageName - Need ReaderWriter Lock
             * If values are ABS larger
             *      Write delta
             * Store last ETag for servers we've successfully rpelicated to
             */
            ReplicationMessage replicationMessage;

            CounterStorage.MetricsCounters.IncomingReplications.Mark();

            try
            {
                replicationMessage = await ReadJsonObjectAsync <ReplicationMessage>().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest, e.Message));
            }

            long lastEtag     = 0;
            var  wroteCounter = false;

            using (var writer = CounterStorage.CreateWriter())
            {
                var counterChangeNotifications = new List <ChangeNotification>();
                foreach (var counter in replicationMessage.Counters)
                {
                    lastEtag = Math.Max(counter.Etag, lastEtag);
                    var singleCounterValue  = writer.GetSingleCounterValue(counter.GroupName, counter.CounterName, counter.ServerId, counter.Sign);
                    var currentCounterValue = singleCounterValue.Value;

                    //if current counter exists and current value is less than received value
                    if ((currentCounterValue != -1 && counter.Value < currentCounterValue) ||
                        (counter.Value == currentCounterValue && (singleCounterValue.DoesCounterExist || writer.IsTombstone(counter.ServerId))))
                    {
                        continue;
                    }

                    wroteCounter = true;
                    var counterChangeAction = writer.Store(counter.GroupName, counter.CounterName, counter.ServerId, counter.Sign, counter.Value);

                    counterChangeNotifications.Add(new ChangeNotification
                    {
                        GroupName   = counter.GroupName,
                        CounterName = counter.CounterName,
                        Delta       = counter.Value - currentCounterValue,
                        Action      = counterChangeAction
                    });
                }

                var serverId = replicationMessage.ServerId;
                if (wroteCounter || writer.GetLastEtagFor(serverId) < lastEtag)
                {
                    writer.RecordSourceNameFor(serverId, replicationMessage.SendingServerName);
                    writer.RecordLastEtagFor(serverId, lastEtag);
                    writer.Commit();

                    using (var reader = CounterStorage.CreateReader())
                    {
                        counterChangeNotifications.ForEach(change =>
                        {
                            change.Total = reader.GetCounterTotal(change.GroupName, change.CounterName);
                            CounterStorage.Publisher.RaiseNotification(change);
                        });
                    }
                }

                return(GetEmptyMessage());
            }
        }
Beispiel #12
0
        public async Task <HttpResponseMessage> CountersBatch()
        {
            if (string.IsNullOrEmpty(GetQueryStringValue("no-op")) == false)
            {
                // this is a no-op request which is there just to force the client HTTP layer to handle the authentication
                // only used for legacy clients
                return(GetEmptyMessage());
            }
            if ("generate-single-use-auth-token".Equals(GetQueryStringValue("op"), StringComparison.InvariantCultureIgnoreCase))
            {
                // using windows auth with anonymous access = none sometimes generate a 401 even though we made two requests
                // instead of relying on windows auth, which require request buffering, we generate a one time token and return it.
                // we KNOW that the user have access to this db for writing, since they got here, so there is no issue in generating
                // a single use token for them.

                var authorizer = (MixedModeRequestAuthorizer)Configuration.Properties[typeof(MixedModeRequestAuthorizer)];

                var token = authorizer.GenerateSingleUseAuthToken(CountersName, User);
                return(GetMessageWithObject(new
                {
                    Token = token
                }));
            }

            CounterStorage.MetricsCounters.ClientRequests.Mark();
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Server.ScriptTimeout = 60 * 60 * 6; // six hours should do it, I think.
            }
            var sp                 = Stopwatch.StartNew();
            var status             = new BatchStatus();
            var timeoutTokenSource = new CancellationTokenSource();
            var counterChanges     = 0;

            var operationId = ExtractOperationId();
            var inputStream = await InnerRequest.Content.ReadAsStreamAsync().ConfigureAwait(false);

            var task = Task.Factory.StartNew(() =>
            {
                var timeout       = timeoutTokenSource.TimeoutAfter(SystemConfiguration.Counter.BatchTimeout);
                var changeBatches = YieldChangeBatches(inputStream, timeout, countOfChanges => counterChanges += countOfChanges);
                try
                {
                    foreach (var changeBatch in changeBatches)
                    {
                        using (var writer = CounterStorage.CreateWriter())
                        {
                            CounterStorage.Publisher.RaiseNotification(new BulkOperationNotification
                            {
                                Type        = BatchType.Started,
                                OperationId = operationId
                            });

                            foreach (var change in changeBatch)
                            {
                                var verificationResult = VerifyGroupAndCounterName(change.Group, change.Name);
                                if (verificationResult != null)
                                {
                                    throw new ArgumentException("Missing group or counter name");
                                }
                                writer.Store(change.Group, change.Name, change.Delta);
                            }
                            writer.Commit();

                            CounterStorage.Publisher.RaiseNotification(new BulkOperationNotification
                            {
                                Type        = BatchType.Ended,
                                OperationId = operationId
                            });
                        }
                    }
                    status.MarkCompleted(string.Format("Counters: {0}", counterChanges));
                }
                catch (OperationCanceledException)
                {
                    // happens on timeout
                    CounterStorage.Publisher.RaiseNotification(new BulkOperationNotification
                    {
                        Type        = BatchType.Error,
                        OperationId = operationId,
                        Message     = "Operation cancelled, likely because of a batch timeout"
                    });

                    status.MarkCanceled("Operation cancelled, likely because of a batch timeout");
                    throw;
                }
                catch (Exception e)
                {
                    var errorMessage = e.SimplifyException().Message;
                    CounterStorage.Publisher.RaiseNotification(new BulkOperationNotification
                    {
                        Type        = BatchType.Error,
                        OperationId = operationId,
                        Message     = errorMessage
                    });

                    status.MarkFaulted(errorMessage);
                    throw;
                }
                finally
                {
                    status.Counters = counterChanges;
                }
            }, timeoutTokenSource.Token);


            long id;

            DatabasesLandlord.SystemDatabase.Tasks.AddTask(task, status, new TaskActions.PendingTaskDescription
            {
                StartTime   = SystemTime.UtcNow,
                TaskType    = TaskActions.PendingTaskType.CounterBatchOperation,
                Description = operationId.ToString()
            }, out id, timeoutTokenSource);

            AddRequestTraceInfo(log =>
                                log.AppendFormat("\tCounters batch operation received {0:#,#;;0} changes in {1}, long running task Id : {2}", counterChanges, sp.Elapsed, id));

            task.Wait(timeoutTokenSource.Token);

            return(GetMessageWithObject(new
            {
                OperationId = id
            }, HttpStatusCode.Accepted));
        }