예제 #1
0
        /// <summary>
        /// Fetches the data for languages specified by <code>cultures</code> and merges / adds it to internally used dictionaries.
        /// </summary>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages in which to fetch the data</param>
        /// <param name="clearExistingData">Value indicating whether the internally used dictionaries should be cleared before fetched data is added</param>
        /// <returns>A <see cref="Task" /> representing the async operation</returns>
        private async Task FetchAndMergeAll(IEnumerable <CultureInfo> cultures, bool clearExistingData)
        {
            Contract.Requires(cultures != null && cultures.Any());

            var cultureInfos = cultures as IReadOnlyList <CultureInfo> ?? cultures.ToList();

            Metric.Context("CACHE").Meter("SportDataCache->FetchAndMergeAll", Unit.Calls).Mark($"Getting for cultures='{string.Join(",", cultureInfos.Select(c => c.TwoLetterISOLanguageName))}'.");

            var fetchTasks = cultureInfos.Select(c => _dataRouterManager.GetAllSportsAsync(c)).ToList();

            fetchTasks.AddRange(cultureInfos.Select(c => _dataRouterManager.GetAllTournamentsForAllSportAsync(c)).ToList());
            fetchTasks.AddRange(cultureInfos.Select(c => _dataRouterManager.GetAllLotteriesAsync(c)).ToList());

            if (clearExistingData)
            {
                FetchedCultures.Clear();
                Categories.Clear();
                Sports.Clear();
            }

            await Task.WhenAll(fetchTasks).ConfigureAwait(false);

            foreach (var culture in cultureInfos)
            {
                FetchedCultures.Add(culture);
            }
        }
예제 #2
0
        /// <summary>
        /// Handles the <see cref="IMessageReceiver.FeedMessageReceived"/> event
        /// </summary>
        /// <param name="sender">A <see cref="object"/> representation of the instance raising the event</param>
        /// <param name="e">A <see cref="FeedMessageReceivedEventArgs"/> instance containing event information</param>
        private void OnMessageReceived(object sender, FeedMessageReceivedEventArgs e)
        {
            var message          = e.Message;
            var validationResult = _messageValidator.Validate(message);

            switch (validationResult)
            {
            case ValidationResult.FAILURE:
                Log.Warn($"{WriteMessageInterest()}Validation of message=[{message}] failed. Raising OnUnparsableMessageReceived event");
                var messageType = _messageDataExtractor.GetMessageTypeFromMessage(message);

                var eventArgs = new UnparsableMessageEventArgs(messageType, message.ProducerId.ToString(), message.EventId, e.RawMessage);
                Dispatch(OnUnparsableMessageReceived, eventArgs, "OnUnparsableMessageReceived");
                return;

            case ValidationResult.PROBLEMS_DETECTED:
                Log.Warn($"{WriteMessageInterest()}Problems were detected while validating message=[{message}], but the message is still eligible for further processing.");
                _messageProcessor.ProcessMessage(message, MessageInterest, e.RawMessage);
                return;

            case ValidationResult.SUCCESS:
                Metric.Context("FEED").Meter($"FeedSession->MessageReceived ({MessageInterest.ProducerId})", Unit.Items).Mark();
                Log.Debug($"{WriteMessageInterest()}Message=[{message}] successfully validated. Continuing with message processing.");
                _messageProcessor.ProcessMessage(message, MessageInterest, e.RawMessage);
                return;

            default:
                Log.Error($"{WriteMessageInterest()}ValidationResult {Enum.GetName(typeof(ValidationResult), validationResult)} is not supported. Aborting processing of message=[{message}].");
                return;
            }
        }
예제 #3
0
        public async Task MemoizeAsync_BackgroundRefreshFails_TTLNotExtended()
        {
            var args        = new object[] { "someString" };
            var refreshTask = new TaskCompletionSource <Thing>();

            refreshTask.SetException(new Exception("Boo!!"));
            var dataSource = CreateDataSource(5, refreshTask, 7);

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0. No data in cache, should retrieve value from source (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // T = 2. Past refresh time (1s), this triggers refresh in background, should get existing value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // T = 3. Background refresh failed, but TTL (4s) not expired yet. Should still give old value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // T = 5. We're past the original TTL (4s), and refresh task failed. Items should have been evicted from cache by now.
            // New item (7) should come in.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7);
            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }
예제 #4
0
        public ServiceProxyProvider(string serviceName, IEventPublisher <ClientCallEvent> eventPublisher,
                                    ICertificateLocator certificateLocator,
                                    ILog log,
                                    Func <string, ReachabilityCheck, IMultiEnvironmentServiceDiscovery> serviceDiscoveryFactory,
                                    Func <DiscoveryConfig> getConfig,
                                    JsonExceptionSerializer exceptionSerializer)
        {
            EventPublisher     = eventPublisher;
            CertificateLocator = certificateLocator;

            Log = log;

            ServiceName         = serviceName;
            GetDiscoveryConfig  = getConfig;
            ExceptionSerializer = exceptionSerializer;

            var metricsContext = Metric.Context(METRICS_CONTEXT_NAME).Context(ServiceName);

            _serializationTime   = metricsContext.Timer("Serialization", Unit.Calls);
            _deserializationTime = metricsContext.Timer("Deserialization", Unit.Calls);
            _roundtripTime       = metricsContext.Timer("Roundtrip", Unit.Calls);

            _successCounter              = metricsContext.Counter("Success", Unit.Calls);
            _failureCounter              = metricsContext.Counter("Failed", Unit.Calls);
            _hostFailureCounter          = metricsContext.Counter("HostFailure", Unit.Calls);
            _applicationExceptionCounter = metricsContext.Counter("ApplicationException", Unit.Calls);

            ServiceDiscovery = serviceDiscoveryFactory(serviceName, ValidateReachability);
        }
예제 #5
0
 private static MetricsData GetMetricsData()
 {
     return
         (Metric.Context(ServiceProxyProvider.METRICS_CONTEXT_NAME)
          .Context(SERVICE_NAME)
          .DataProvider.CurrentMetricsData);
 }
예제 #6
0
 private static MetricsData GetMetricsData()
 {
     return
         (Metric.Context("Service")
          .Context(CurrentApplicationInfo.Name)
          .DataProvider.CurrentMetricsData);
 }
예제 #7
0
        public async Task MemoizeAsync_BackgroundRefreshFails_TTLNotExtended()
        {
            var args        = new object[] { "someString" };
            var refreshTask = new TaskCompletionSource <Thing>();

            refreshTask.SetException(new MissingFieldException("Boo!!"));
            var dataSource = CreateDataSource(870, refreshTask, 1002);

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener(), () => new RevokeConfig()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0s. No data in cache, should retrieve value from source (870).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

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

            // T = 2s. Past refresh time (1s), this triggers refresh in background (that will fail), should get existing value (870)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

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

            // T = 4s. Background refresh failed, but TTL (5s) not expired yet. Should still give old value (870) but won't
            // trigger additional background refresh because of very long FailedRefreshDelay that was spcified (100s).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

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

            // T = 6s. We're past the original TTL (5s), and refresh task failed. Items should have been evicted from cache by now
            // according to 5s expiery from T=0s, not from T=2s of the failed refresh. New item (1002) should come in.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1))).Id.ShouldBe(1002);
            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }
예제 #8
0
        private async Task <Stream> GetHistoryCcfChangeAsync(DateTime startDate,
                                                             DateTime endDate,
                                                             int?bookmakerId = null,
                                                             IReadOnlyCollection <int> subBookmakerIds = null,
                                                             string sourceId       = null,
                                                             SourceType sourceType = SourceType.Customer,
                                                             string username       = null,
                                                             string password       = null)
        {
            Metric.Context("ReportManager").Meter("GetHistoryCcfChangeAsync", Unit.Calls).Mark();
            InteractionLog.Info($"Called GetHistoryCcfChangeAsync for period: {startDate} - {endDate}");

            var fullUri = new Uri(_ccfChangeHistoryUri);

            try
            {
                var token = await _mtsAuthService.GetTokenAsync(username, password).ConfigureAwait(false);

                fullUri = GenerateFullUri(startDate, endDate, bookmakerId, subBookmakerIds, sourceId, sourceType);
                var resultStream = await _ccfChangeHistoryFetcher.GetDataAsync(token, fullUri).ConfigureAwait(false);

                return(resultStream);
            }
            catch (Exception e)
            {
                ExecutionLog.Error(e.Message, e);
                ExecutionLog.Warn($"Getting ccf changes from url={fullUri} failed.");
                throw;
            }
        }
예제 #9
0
        static XMLLogParser()
        {
            var xmlParserContext = Metric.Context("XMLLogParser");

            getElementPathTypeCounter         = xmlParserContext.Counter("GetElementDataFromPath Path Type", Unit.Items, "xml, log, parser, get, attribute, path");
            getElementFilterTypeCounter       = xmlParserContext.Counter("GetElementDataFromPath Filter Type", Unit.Items, "xml, log, parser, get, attribute, filter");
            unknownTopNodeTypeCounter         = xmlParserContext.Counter("Unknown Top Node Type", Unit.Errors, "xml, log, parser, get, attribute, unknown");
            failureToAddAttributeToLogCounter = xmlParserContext.Counter("Failure to Add Attribute to Log", Unit.Errors, "xml, log, parser, process, element, failure, add");
            attributesParsedHistogram         = xmlParserContext.Histogram("Attributes Parsed", Unit.Items, tags: "xml, log, parser, process, element, items");
            processElementCounter             = xmlParserContext.Counter("ProcessElement", Unit.Calls, "xml, log, parser, process, element");
            {
                var subContext = xmlParserContext.Context("Parse");
                processElementTimer      = subContext.Timer("ProcessElement", Unit.Calls, tags: "xml, log, parser, parse, process");
                xmlElementCounter        = subContext.Counter("XML Element", Unit.Items, "xml, log, parser, parse, element");
                xmlCDATACounter          = subContext.Counter("XML CDATA", Unit.Items, "xml, log, parser, parse, text, cdata");
                xmlTextCounter           = subContext.Counter("XML Text", Unit.Items, "xml, log, parser, parse, text");
                unknownXmlElementCounter = subContext.Counter("Unknown XML Types", Unit.Items, "xml, log, parser, parse, unknown");
                parseCounter             = subContext.Counter("Unknown XML Types", Unit.Items, "xml, log, parser, parse, unknown");
                xmlRootUnfinishedCounter = subContext.Counter("XML root Unfinished", Unit.Errors, "xml, log, parser, parse, root, unfinished");
            }
            parseCounter = xmlParserContext.Counter("Parse", Unit.Calls, "xml, log, parser, parse");
            setConfigFailureHandlingCounter = xmlParserContext.Counter("SetConfig", Unit.Calls, "xml, log, parser, config, failure, handle");
            {
                var subContext = xmlParserContext.Context("Context");
                contextApplyConfigCounter        = subContext.Counter("ApplyConfig", Unit.Calls, "xml, log, parser, context, config");
                contextApplyConfigSizeHistogram  = subContext.Histogram("ApplyConfig Size", Unit.Items, tags: "xml, log, parser, context, config, size");
                contextApplyContextConfigCounter = subContext.Counter("ApplyContextConfig", Unit.Calls, "xml, log, parser, context, config");
                contextParseCounter = subContext.Counter("Parse", Unit.Calls, "xml, log, parser, context, parse");
            }
            applyContextConfigCounter = xmlParserContext.Counter("ApplyContextConfig", Unit.Calls, "xml, log, parser, context, config");
        }
        static LogRegistryExtensions()
        {
            var logRegistryExtContext = Metric.Context("LogRegistry Extensions");

            getByCounter          = logRegistryExtContext.Counter("GetBy", Unit.Calls, "log, registry");
            getByTimestampCounter = logRegistryExtContext.Counter("GetByTimetstamp", Unit.Calls, "log, registry");
        }
예제 #11
0
        public void Init(IProviderConfiguration config, string providerName, Logger logger, IServiceProvider serviceProvider)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (String.IsNullOrEmpty(providerName))
            {
                throw new ArgumentNullException(nameof(providerName));
            }

            // Creating an options object with all the config values
            _options = new KafkaStreamProviderOptions(config);

            if (!_options.UsingExternalMetrics)
            {
                Metric.Config.WithHttpEndpoint($"http://localhost:{_options.MetricsPort}/");
            }

            if (!_options.IncludeMetrics)
            {
                Metric.Context("KafkaStreamProvider").Advanced.CompletelyDisableMetrics();
            }

            _providerName      = providerName;
            _streamQueueMapper = new HashRingBasedStreamQueueMapper(_options.NumOfQueues, providerName);
            _logger            = logger;
            _adapter           = new KafkaQueueAdapter(_streamQueueMapper, _options, providerName, new KafkaBatchFactory(), _logger);
            _adapterCache      = new TimedQueueAdapterCache(this, TimeSpan.FromSeconds(_options.CacheTimespanInSeconds), _options.CacheSize, _options.CacheNumOfBuckets, logger);
        }
예제 #12
0
        internal ScorpionMonitorImplement(string contextName, SMConfig config)
        {
            if (null != Context)
            {
                Console.WriteLine("!!!!!!!!!!!!Error: null != Context");
                return;
            }
            Context = Metric.Context(contextName);
            var metricConfig = new MetricsConfig(Context);

            metricConfig.WithReporting(report =>
            {
                if (config.ConsoleReport)
                {
                    report.WithConsoleReport(TimeSpan.FromSeconds(config.ConsoleFreq));
                }
                if (config.DBReport)
                {
                    report.WithInflux(config.Ip, config.Port, config.User, config.Password, config.DBName, TimeSpan.FromSeconds(config.DBFreq), new ConfigOptions
                    {
                        UseHttps = config.SSL,
                    });
                }
            });
        }
예제 #13
0
        private void OnMqMessageReceived(object sender, MessageReceivedEventArgs eventArgs)
        {
            var stopwatch = Stopwatch.StartNew();

            if (ExecutionLog.IsDebugEnabled)
            {
                ExecutionLog.Debug($"Received ticket response for correlationId={eventArgs.CorrelationId} and routingKey={eventArgs.RoutingKey}. JSON={eventArgs.JsonBody}");
            }
            else
            {
                ExecutionLog.Info($"Received ticket response for correlationId={eventArgs.CorrelationId}.");
            }

            ISdkTicket ticket;

            try
            {
                ticket = _entitiesMapper.GetTicketResponseFromJson(eventArgs.JsonBody, eventArgs.RoutingKey, eventArgs.ResponseType, eventArgs.CorrelationId, eventArgs.AdditionalInfo);
                ((ConnectionStatus)ConnectionStatus).TicketReceived(ticket.TicketId);
            }
            catch (Exception e)
            {
                ExecutionLog.Debug("Received message deserialization failed.", e);
                //deserialization failed
                OnMqMessageDeserializationFailed(sender, new MessageDeserializationFailedEventArgs(Encoding.UTF8.GetBytes(eventArgs.JsonBody)));
                return;
            }

            // first clean it from awaiting ticket response
            lock (_lockForTicketsForNonBlockingRequestsCache)
            {
                if (_ticketsForNonBlockingRequests.Contains(ticket.TicketId))
                {
                    _ticketsForNonBlockingRequests.Remove(ticket.TicketId);
                }
            }

            //ExecutionLog.Debug($"Processing ticket response from JSON (time: {stopwatch.ElapsedMilliseconds} ms).");

            // check if it was called from SendBlocking
            if (_autoResetEventsForBlockingRequests.ContainsKey(ticket.TicketId))
            {
                _responsesFromBlockingRequests.TryAdd(ticket.TicketId, ticket);
                ReleaseAutoResetEventFromDictionary(ticket.TicketId);
                return;
            }
            //ExecutionLog.Debug($"Processing ticket response from AutoResetEvent (time: {stopwatch.ElapsedMilliseconds} ms).");

            //else raise event
            var ticketReceivedEventArgs = new TicketResponseReceivedEventArgs(ticket);

            Metric.Context("MtsSdk").Meter("TicketReceived", Unit.Items).Mark(ticketReceivedEventArgs.Type.ToString());

            ExecutionLog.Info($"Invoking TicketResponseReceived event for {eventArgs.ResponseType} response with correlationId={eventArgs.CorrelationId}.");

            TicketResponseReceived?.Invoke(this, ticketReceivedEventArgs);

            stopwatch.Stop();
            ExecutionLog.Info($"Processing TicketResponseReceived event for {eventArgs.ResponseType} response with correlationId={eventArgs.CorrelationId} finished in {stopwatch.ElapsedMilliseconds} ms.");
        }
예제 #14
0
        /// <summary>
        /// Asynchronously gets a <see cref="SportData"/> representing sport associated with the tournament specified by it's id. Note that the hierarchy will only contain the
        /// specified tournament and it's parent category not all categories / tournaments in the hierarchy
        /// </summary>
        /// <param name="tournamentId">A <see cref="URN"/> specifying the id of the tournament whose parent sport should be retrieved</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}"/> specifying the languages in which the data is returned</param>
        /// <returns>A <see cref="Task{SportData}"/> representing the asynchronous operation</returns>
        public async Task <SportData> GetSportForTournamentAsync(URN tournamentId, IEnumerable <CultureInfo> cultures)
        {
            Metric.Context("CACHE").Meter("SportDataCache->GetSportForTournamentAsync", Unit.Calls).Mark();

            var cultureList = cultures as IList <CultureInfo> ?? cultures.ToList();

            if (!await _semaphore.WaitAsyncSafe().ConfigureAwait(false))
            {
                return(null);
            }

            var missingCultures = cultureList.Where(c => !FetchedCultures.Contains(c)).ToList();

            try
            {
                if (missingCultures.Any())
                {
                    await FetchAndMergeAll(missingCultures, false).ConfigureAwait(false);
                }
                //return GetSportForTournamentFromCache(tournamentId, cultureList, false);
            }
            catch (Exception ex)
            {
                ExecutionLog.Warn($"An exception occurred while attempting to fetch sport data for tournament: id={tournamentId}, cultures={string.Join(",", cultureList)}. Exception: {ex}");
                return(null);
            }
            finally
            {
                _semaphore.ReleaseSafe();
            }

            var sport = GetSportForTournamentFromCache(tournamentId, cultureList, true);

            return(sport);
        }
        public MultiContextInstanceMetrics(string instanceName)
        {
            var context = Metric.Context(instanceName);

            _instanceCounter = context.Counter("Sample Counter", Unit.Errors);
            _instanceTimer   = context.Timer("Sample Timer", Unit.Requests);
        }
예제 #16
0
 private MetricsData GetMetricsData(string hostName)
 {
     return
         (Metric.Context("Service")
          .Context(hostName)
          .DataProvider.CurrentMetricsData);
 }
예제 #17
0
 private static MetricsData GetMetricsData(string subContext)
 {
     return
         (Metric.Context(cacheContextName)
          .Context(subContext)
          .DataProvider.CurrentMetricsData);
 }
예제 #18
0
        /// <summary>
        /// Gets a <see cref="SportEventCI"/> instance representing cached sport event data
        /// </summary>
        /// <param name="id">A <see cref="URN"/> specifying the id of the sport event which cached representation to return</param>
        /// <returns>a <see cref="SportEventCI"/> instance representing cached sport event data</returns>
        public SportEventCI GetEventCacheItem(URN id)
        {
            Metric.Context("CACHE").Meter("SportEventCache->GetEventCacheItem", Unit.Calls);

            lock (_addLock)
            {
                try
                {
                    var item = (SportEventCI)Cache.Get(id.ToString());
                    if (item != null)
                    {
                        return(item);
                    }

                    item = _sportEventCacheItemFactory.Build(id);

                    AddNewCacheItem(item);

                    // if there are events for non-standard tournaments (tournaments not on All tournaments for all sports)
                    if (item is TournamentInfoCI && !SpecialTournaments.Contains(item.Id))
                    {
                        SpecialTournaments.Add(item.Id);
                    }

                    return(item);
                }
                catch (Exception ex)
                {
                    ExecutionLog.Error($"Error getting cache item for id={id}", ex);
                }
            }
            return(null);
        }
예제 #19
0
        public async Task MemoizeAsync_CallAfterRefreshTime_TTLNotExpired()
        {
            var dataSource = CreateDataSource(5, 7, 9);
            var args       = new object[] { "someString" };

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener(), () => new RevokeConfig()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0s. No data in cache, should retrieve value from source (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // T = 2s. Refresh just triggered, should get old value (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // T = 2.5s. Refresh task should have completed by now, verify new value. Should not trigger another refresh.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7);

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

            // T = 5s. We're past the original TTL (from T=0s) but not past the refreshed TTL (from T=2s). Should still
            // return the refreshed value (7), not another (9). If (9) was returned, it means the data source was accessed
            // again, probably because the TTL expired (it shouldn't, every refresh should extend the TTL). This should also
            // trigger another refresh.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // new value is expected now

            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }
        /// <summary>
        /// Gets the cached <see cref="SportEventStatusCI" /> instance associated with the sport event specified by the <code>eventId</code>. If the instance associated
        /// with the specified event is not found, it tries to obtain it via API, if still cant, a <see cref="SportEventStatusCI" /> instance indicating a 'not started' event is returned.
        /// </summary>
        /// <param name="eventId">A <see cref="URN" /> representing the id of the sport event whose status to get</param>
        /// <returns>A <see cref="SportEventStatusCI" /> representing the status of the specified sport event</returns>
        public async Task <SportEventStatusCI> GetSportEventStatusAsync(URN eventId)
        {
            if (_isDisposed)
            {
                return(null);
            }

            Guard.Argument(eventId, nameof(eventId)).NotNull();

            var timer = Metric.Context("DataRouterManager").Timer("GetSportEventStatusAsync", Unit.Requests);

            // ReSharper disable once UnusedVariable
            using (var t = timer.NewContext($"{eventId}"))
            {
                try
                {
                    // fetch from api
                    await _fetchSemaphore.WaitAsync().ConfigureAwait(false);

                    // get from cache
                    lock (_lock) // lock needed because of adding to cache in other methods
                    {
                        var item = _sportEventStatusCache.Get(eventId.ToString());

                        if (item != null)
                        {
                            return((SportEventStatusCI)item);
                        }
                    }

                    var cachedEvent = _sportEventCache.GetEventCacheItem(eventId) as ICompetitionCI;
                    if (cachedEvent != null)
                    {
                        Metric.Context("CACHE").Meter("SportEventStatusCache->FetchSportEventStatusAsync", Unit.Calls).Mark();
                        await cachedEvent.FetchSportEventStatusAsync().ConfigureAwait(false);
                    }

                    // get from cache
                    lock (_lock) // lock needed because of adding to cache in other methods
                    {
                        var item = _sportEventStatusCache.Get(eventId.ToString());

                        if (item != null)
                        {
                            return((SportEventStatusCI)item);
                        }
                    }
                }
                finally
                {
                    //var msg = $"GetSportEventStatusAsync: {eventId} returns status in {t.Elapsed.TotalMilliseconds} ms.";
                    if (!_isDisposed)
                    {
                        _fetchSemaphore.Release();
                    }
                }
            }

            return(((SportEventStatusMapperBase)_mapperFactory).CreateNotStarted());
        }
예제 #21
0
        /// <summary>
        /// Asynchronously gets a match stats descriptions specified by the language specified by <code>culture</code>
        /// </summary>
        /// <param name="culture">A <see cref="CultureInfo"/> specifying the language of the retrieved match statuses</param>
        /// <returns>A <see cref="Task" /> representing the retrieval operation</returns>
        private async Task FetchAndMerge(CultureInfo culture)
        {
            Guard.Argument(culture, nameof(culture)).NotNull();

            Metric.Context("CACHE").Meter("LocalizedNamedValueCache->FetchAndMerge", Unit.Calls);
            var record = await _dataProvider.GetDataAsync(culture.TwoLetterISOLanguageName).ConfigureAwait(false);

            lock (_lock)
            {
                foreach (var item in record.Items)
                {
                    IDictionary <CultureInfo, string> trans;
                    if (_namedValues.TryGetValue(item.Id, out trans))
                    {
                        trans[culture] = item.Description;
                    }
                    else
                    {
                        trans = new Dictionary <CultureInfo, string> {
                            { culture, item.Description }
                        };
                        _namedValues.Add(item.Id, trans);
                    }
                }
                _loadedCultures.Add(culture);
            }
            CacheLog.Debug($"LocalizedNamedValueCache: {record.Items.Count()} items retrieved for locale '{culture.TwoLetterISOLanguageName}'.");
        }
예제 #22
0
        public override void Load()
        {
            //Need to be initialized before using any regex!
            new RegexTimeoutInitializer().Init();
            Kernel.Bind(typeof(DisposableCollection <,>)).ToSelf().InSingletonScope();
            if (Kernel.CanResolve <Func <long, DateTime> >() == false)
            {
                Kernel.Load <FuncModule>();
            }

            this.BindClassesAsSingleton(NonSingletonBaseTypes, typeof(ConfigurationAssembly), typeof(ServiceProxyAssembly));
            this.BindInterfacesAsSingleton(NonSingletonBaseTypes, new List <Type> {
                typeof(ILog)
            },
                                           typeof(ConfigurationAssembly),
                                           typeof(ServiceProxyAssembly),
                                           typeof(SharedLogicAssembly),
                                           typeof(ServiceDiscoveryAssembly));


            Bind <IRemoteHostPoolFactory>().ToFactory();

            Kernel.BindPerKey <string, ReportingStrategy, IPassiveAggregatingHealthCheck, PassiveAggregatingHealthCheck>();

            Kernel.BindPerKey <string, ReachabilityCheck, IMultiEnvironmentServiceDiscovery, MultiEnvironmentServiceDiscovery>();
            Kernel.BindPerKey <string, ReachabilityChecker, IServiceDiscovery, ServiceDiscovery.ServiceDiscovery>();
            Kernel.BindPerString <IServiceProxyProvider, ServiceProxyProvider>();
            Kernel.BindPerString <AggregatingHealthStatus>();

            Rebind <MetricsContext>()
            .ToMethod(c => Metric.Context(GetTypeOfTarget(c).Name))
            .InScope(GetTypeOfTarget);

            Rebind <IServiceDiscoverySource>().To <ConsulDiscoverySource>().InTransientScope();
            Bind <IServiceDiscoverySource>().To <LocalDiscoverySource>().InTransientScope();
            Bind <IServiceDiscoverySource>().To <ConfigDiscoverySource>().InTransientScope();

            Bind <INodeSourceFactory>().To <ConsulNodeSourceFactory>().InTransientScope();
            Rebind <ILoadBalancer>().To <LoadBalancer>().InTransientScope();
            Rebind <NodeMonitoringState>().ToSelf().InTransientScope();
            Bind <IDiscovery>().To <Discovery>().InSingletonScope();

            Rebind <ServiceDiscovery.Rewrite.ConsulClient, ServiceDiscovery.Rewrite.IConsulClient>()
            .To <ServiceDiscovery.Rewrite.ConsulClient>().InSingletonScope();


            Kernel.Rebind <IConsulClient>().To <ConsulClient>().InTransientScope();
            Kernel.Load <ServiceProxyModule>();

            Kernel.Rebind <IConfigObjectsCache>().To <ConfigObjectsCache>().InSingletonScope();
            Kernel.Rebind <IConfigObjectCreator>().To <ConfigObjectCreator>().InTransientScope();
            Kernel.Bind <IConfigEventFactory>().To <ConfigEventFactory>();
            Kernel.Bind <IConfigFuncFactory>().ToFactory();

            // ServiceSchema is at ServiceContracts, and cannot be depended on IServiceInterfaceMapper, which belongs to Microdot
            Kernel.Rebind <ServiceSchema>()
            .ToMethod(c => new ServiceSchema(c.Kernel.Get <IServiceInterfaceMapper>().ServiceInterfaceTypes.ToArray())).InSingletonScope();

            Kernel.Rebind <SystemInitializer.SystemInitializer>().ToSelf().InSingletonScope();
        }
예제 #23
0
        public async Task <long> GetMaxStakeAsync(ITicket ticket, string username, string password)
        {
            Guard.Argument(ticket, nameof(ticket)).NotNull();

            Metric.Context("MtsClientApi").Meter("GetMaxStakeAsync", Unit.Calls).Mark();
            InteractionLog.Info($"Called GetMaxStakeAsync with ticketId={ticket.TicketId}.");

            try
            {
                var token = await _mtsAuthService.GetTokenAsync(username, password).ConfigureAwait(false);

                var content  = new StringContent(ticket.ToJson(), Encoding.UTF8, "application/json");
                var maxStake = await _maxStakeDataProvider.PostDataAsync(token, content, new[] { "" }).ConfigureAwait(false);

                if (maxStake == null)
                {
                    throw new Exception("Failed to get max stake.");
                }
                return(maxStake.MaxStake);
            }
            catch (Exception e)
            {
                ExecutionLog.Error(e.Message, e);
                ExecutionLog.Warn($"Getting max stake for ticketId={ticket.TicketId} failed.");
                throw;
            }
        }
예제 #24
0
        static LogRegistryFactory()
        {
            var printerContext = Metric.Context("LogRegistry Factory");

            factoryCreationCounter = printerContext.Counter("Creation", Unit.Calls, "log, registry, factory");
            creationCounter        = printerContext.Counter("Usage", Unit.Calls, "log, registry");
        }
예제 #25
0
        static PrinterFactory()
        {
            var printerContext = Metric.Context("Printer Factory");

            factoryCreationCounter = printerContext.Counter("Creation", Unit.Calls, "printer, factory");
            creationCounter        = printerContext.Counter("Usage", Unit.Calls, "printer");
        }
예제 #26
0
        /// <summary>
        /// Invoked when the timer used to check the status of trackers is invoked
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void OnTimerElapsed(object source, EventArgs e)
        {
            if (!IsOpened)
            {
                return;
            }

            Metric.Context("FEED").Meter("FeedRecoveryManager->OnTimerElapsed", Unit.Calls).Mark();

            foreach (var recoveryTracker in _producerRecoveryManagers.Values)
            {
                recoveryTracker.CheckStatus();
            }

            try
            {
                if (_isOpened != 0)
                {
                    _inactivityTimer.FireOnce(TimeSpan.FromSeconds(TrackersCheckPeriodSeconds));
                }
            }
            catch (ObjectDisposedException ex)
            {
                _executionLog.Info($"Error happened during invoking timer, because the instance {ex.ObjectName} is being disposed.");
            }
        }
예제 #27
0
        public async Task MemoizeAsync_CallAfterRefreshTime_TTLNotExpired()
        {
            var dataSource = CreateDataSource(5, 7, 9);
            var args       = new object[] { "someString" };

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener()), new MetadataProvider(), Metric.Context("Tests"));

            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

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

            // Refresh just triggered, should get old value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5); // value is not refreshed yet. it is running on background

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

            // Complete refresh task and verify new value
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // value is not refreshed yet. it is running on background

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

            // We're past the original TTL, should still be the refreshed value (7), not another (9).
            // If 9 was returned, it means the data source was accessed again, probably because the TTL expired
            // (it shouldn't, every refresh should extend the TTL).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // new value is expected now
            dataSource.Received(2).ThingifyTaskThing(Arg.Any <string>());
        }
        public KafkaQueueAdapterReceiver(QueueId queueId, IManualConsumer consumer, KafkaStreamProviderOptions options,
                                         IKafkaBatchFactory factory, Logger logger)
        {
            // input checks
            if (queueId == null)
            {
                throw new ArgumentNullException(nameof(queueId));
            }
            if (consumer == null)
            {
                throw new ArgumentNullException(nameof(consumer));
            }
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _counterCurrentOffset = Metric.Context("KafkaStreamProvider").Counter($"CurrentOffset queueId:({queueId.GetNumericId()})", unit:  Unit.Custom("Log"));

            _options  = options;
            Id        = queueId;
            _consumer = consumer;
            _factory  = factory;
            _logger   = logger;
        }
예제 #29
0
        public override void Load()
        {
            if (Kernel.CanResolve <Func <long, DateTime> >() == false)
            {
                Kernel.Load <FuncModule>();
            }

            this.BindClassesAsSingleton(NonSingletonBaseTypes, typeof(ConfigurationAssembly), typeof(ServiceProxyAssembly));
            this.BindInterfacesAsSingleton(NonSingletonBaseTypes, typeof(ConfigurationAssembly), typeof(ServiceProxyAssembly), typeof(SharedLogicAssembly), typeof(ServiceDiscoveryAssembly));

            Bind <IRemoteHostPoolFactory>().ToFactory();

            Kernel.BindPerKey <string, ReachabilityChecker, IServiceDiscovery, ServiceDiscovery.ServiceDiscovery>();
            Kernel.BindPerString <IServiceProxyProvider, ServiceProxyProvider>();
            Kernel.BindPerString <AggregatingHealthStatus>();

            Rebind <MetricsContext>()
            .ToMethod(c => Metric.Context(GetTypeOfTarget(c).Name))
            .InScope(GetTypeOfTarget);

            Rebind <IServiceDiscoverySource>().To <ConsulDiscoverySource>().InTransientScope();
            Bind <IServiceDiscoverySource>().To <LocalDiscoverySource>().InTransientScope();
            Bind <IServiceDiscoverySource>().To <ConfigDiscoverySource>().InTransientScope();

            Kernel.BindPerString <IConsulClient, ConsulClient>();

            Kernel.Load <ServiceProxyModule>();
            Kernel.Load <ConfigObjectsModule>();
        }
예제 #30
0
            public OperationMonitor(HttpRequestMessage request)
            {
                string actionName = request.GetActionDescriptor().ActionName;
                var    tags       = new MetricTags(
                    $"method={request.Method.Method}",
                    $"uri={request.RequestUri}",
                    $"version={request.Version}");

                Func <Reservoir> factory = () => new UniformReservoir(3);

                //Func<Reservoir> factory = () => new PlayReservoir();
                _timer = Metric
                         //.Context(key.GetHashCode().ToString())
                         .Context(actionName)
                         .Advanced
                         .Timer(
                    "request_timer",
                    Unit.Requests,
                    factory,
                    tags: tags);

                _counter = Metric
                           .Context(actionName)
                           .Counter(
                    "request_counter",
                    Unit.Requests,
                    tags: tags);
            }