public void Execute(IServiceContext context) { ignite.Logger.Log(LogLevel.Info, $">>> {nameof(EventHandlerService)} simulated initialization delay..."); Thread.Sleep(IngressRate * 2); var inCache = WaitForInputCache(); outCache = ignite.GetOrCreateCache <int, string>(CacheConfiguration(OutCache)); stateCache = ignite.GetOrCreateCache <string, int>("STATE_CACHE"); var qry = new ContinuousQuery <int, string>(new LocalListener(outCache, stateCache)); const string OffsetField = "_KEY"; var offset = stateCache.ContainsKey(LocalListener.OffsetKey) ? stateCache.Get(LocalListener.OffsetKey) : int.MaxValue; var initQry = new SqlQuery(typeof(string), $"FROM {InCache}.STRING WHERE {OffsetField} > ?") { Arguments = new[] { (object)offset } }; qryHandle = inCache.QueryContinuous(qry, initQry); foreach (var entry in qryHandle.GetInitialQueryCursor()) { LocalListener.Action(entry, outCache, stateCache); } ignite.Logger.Log(LogLevel.Info, $">>> {nameof(EventHandlerService)} is executing"); }
/// <summary> /// No-arg constructor. Instantiates the continuous query and performs initial scan of elements that the remote filter /// will populate into the node-local groupers within the mutable grid. /// </summary> public TAGFileBufferQueueManager(bool runLocally) { _log.LogInformation("Establishing Ignite and TAG file buffer queue cache contexts"); // Get the ignite grid and cache references _ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); var queueCache = _ignite.GetCache <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); var handler = new TAGFileBufferQueueItemHandler(); var tagFileFilter = new RemoteTAGFileFilter(handler); _log.LogInformation("Creating continuous query"); // Construct the continuous query machinery // Set the initial query to return all elements in the cache // Instantiate the queryHandle and start the continuous query on the remote nodes // Note: Only cache items held on this local node will be handled here _queryHandle = queueCache.QueryContinuous (qry: new ContinuousQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(new LocalTAGFileListener(handler)) { Local = runLocally, Filter = tagFileFilter }, initialQry: new ScanQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem> { Local = runLocally, Filter = tagFileFilter }); // Perform the initial query to grab all existing elements and add them to the grouper // All processing should happen on the remote node in the implementation of the TAGFileFilter remote filter foreach (var item in _queryHandle.GetInitialQueryCursor()) { _log.LogError( $"A cache entry ({item.Key}) from the TAG file buffer queue was passed back to the local scan query rather than intercepted by the remote filter"); } _log.LogInformation("Completed TAG file buffer queue manager initialization"); }
/// <summary> /// Executes the life cycle of the service until it is aborted /// </summary> public void Execute(IServiceContext context) { try { if (_log == null) { Console.WriteLine($"Error: Null logger present in {nameof(TAGFileBufferQueueService)}.{nameof(Execute)}"); } _log.LogInformation($"{nameof(TAGFileBufferQueueService)} {context.Name} starting executing"); _aborted = false; _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); // Get the ignite grid and cache references var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Mutable) ?? Ignition.GetIgnite(TRexGrids.MutableGridName()); if (ignite == null) { _log.LogError("Ignite reference in service is null - aborting service execution"); return; } // Don't start operations until the local (mutable) grid is confirmed as active DIContext.ObtainRequired <IActivatePersistentGridServer>().WaitUntilGridActive(TRexGrids.MutableGridName()); // Once active, delay start of operations for a time to ensure everything is up and running var delay = DIContext.ObtainRequired <IConfigurationStore>().GetValueInt("TREX_TAG_FILE_BUFFER_QUEUE_SERVICE_OPERATION_START_DELAY_SECONDS", 120); _log.LogInformation($"Delaying start of operations for {delay} seconds"); Thread.Sleep(delay * 1000); _log.LogInformation("Obtaining queue cache reference"); var queueCache = ignite.GetCache <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(TRexCaches.TAGFileBufferQueueCacheName()); _handler = new TAGFileBufferQueueItemHandler(); while (_queryHandle == null && !_aborted) { try { // Construct the continuous query machinery // Set the initial query to return all elements in the cache // Instantiate the queryHandle and start the continuous query on the remote nodes // Note: Only cache items held on this local node will be handled here _log.LogInformation("Obtaining continuous query handle"); _queryHandle = queueCache.QueryContinuous (qry: new ContinuousQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem>(new LocalTAGFileListener(_handler)) { Local = true }, initialQry: new ScanQuery <ITAGFileBufferQueueKey, TAGFileBufferQueueItem> { Local = true }); } catch (Exception e) { _log.LogError(e, "Exception while constructing continuous query, will sleep and retry"); Thread.Sleep(5000); } } if (_queryHandle == null || _aborted) { _log.LogInformation("No query handle available, or aborting"); return; } using (_queryHandle) { // Perform the initial query to grab all existing elements and add them to the grouper _log.LogInformation("Performing initial continuous query cursor scan of items"); _queryHandle.GetInitialQueryCursor().ForEach(item => _handler.Add(item.Key)); // Transition into steady state looking for new elements in the cache via the continuous query while (!_aborted) { try { // Cycle looking for new work to do as TAG files arrive until aborted... _log.LogInformation("Entering steady state continuous query scan of items to process in TAGFileBufferQueue"); do { _waitHandle.WaitOne(_serviceCheckIntervalMs); //Log.LogInformation("Continuous query scan of items to process in TAGFileBufferQueue still active"); } while (!_aborted); } catch (Exception e) { _log.LogError(e, "Tag file buffer service unhandled exception, waiting and trying again"); // Sleep for 5 seconds to see if things come right and then try again Thread.Sleep(5000); } } } _handler.Cancel(); } catch (Exception e) { _log.LogError(e, "Exception occurred performing initial set up of continuous query and scan of existing items"); } finally { _log.LogInformation($"{nameof(TAGFileBufferQueueService)} {context.Name} completed executing"); } }
/// <summary> /// Executes the life cycle of the service until it is aborted /// </summary> public void Execute(IServiceContext context) { try { if (_log == null) { Console.WriteLine($"Error: Null logger present in {nameof(SiteModelChangeProcessorService)}.{nameof(Execute)}"); } _log.LogInformation($"{context.Name} starting executing"); Aborted = false; _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); // Get the ignite grid and cache references var ignite = DIContext.Obtain <ITRexGridFactory>()?.Grid(StorageMutability.Immutable) ?? Ignition.GetIgnite(TRexGrids.ImmutableGridName()); if (ignite == null) { _log.LogError("Ignite reference in service is null - aborting service execution"); return; } // Don't start operations until the local (immutable) grid is confirmed as active DIContext.ObtainRequired <IActivatePersistentGridServer>().WaitUntilGridActive(TRexGrids.ImmutableGridName()); // Once active, delay start of operations for a time to ensure everything is up and running var delay = DIContext.ObtainRequired <IConfigurationStore>().GetValueInt("TREX_SITE_MODEL_CHANGE_MAP_SERVICE_OPERATION_START_DELAY_SECONDS", 120); _log.LogInformation($"Delaying start of operations for {delay} seconds"); Thread.Sleep(delay * 1000); _log.LogInformation("Obtaining queue cache reference"); var queueCache = ignite.GetCache <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(TRexCaches.SiteModelChangeBufferQueueCacheName()); _log.LogInformation($"Obtained queue cache for SiteModelChangeBufferQueueKey: {queueCache}"); var handler = new SiteModelChangeProcessorItemHandler(); var listener = new LocalSiteModelChangeListener(handler); // Obtain the query handle for the continuous query from the DI context, or if not available create it directly // Construct the continuous query machinery // Set the initial query to return all elements in the cache // Instantiate the queryHandle and start the continuous query on the remote nodes // Note: Only cache items held on this local node will be handled here var queryHandleFactory = DIContext.Obtain <Func <LocalSiteModelChangeListener, IContinuousQueryHandle <ICacheEntry <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> > > >(); if (queryHandleFactory != null) { _log.LogInformation("Obtaining query handle from DI factory"); _queryHandle = queryHandleFactory(listener); } while (_queryHandle == null && !Aborted) { _log.LogInformation("Obtaining query handle from QueryContinuous() API"); try { _queryHandle = queueCache.QueryContinuous (qry: new ContinuousQuery <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem>(listener) { Local = true }, initialQry: new ScanQuery <ISiteModelChangeBufferQueueKey, ISiteModelChangeBufferQueueItem> { Local = true }); } catch (Exception e) { _log.LogError(e, "Exception while constructing continuous query, will sleep and retry"); Thread.Sleep(5000); } } if (_queryHandle == null || Aborted) { _log.LogInformation("No query handle available, or aborting"); return; } using (_queryHandle) { _log.LogInformation("Performing initial continuous query cursor scan of items to process"); // Perform the initial query to grab all existing elements and process them. Make sure to sort them in time order first _queryHandle.GetInitialQueryCursor().OrderBy(x => x.Key.InsertUTCTicks).ForEach(handler.Add); while (!Aborted) { try { { // Cycle looking for new work to do as items arrive until aborted... _log.LogInformation("Entering steady state continuous query scan of items to process"); // Activate the handler with the inject initial continuous query and move into steady state processing InSteadyState = true; handler.Activate(); do { _waitHandle.WaitOne(_serviceCheckIntervalMs); } while (!Aborted); } } catch (Exception e) { _log.LogError(e, "Site model change processor service unhandled exception, waiting and trying again"); // Sleep for 5 seconds to see if things come right and then try again Thread.Sleep(5000); } } } handler.Cancel(); } catch (Exception e) { _log.LogError(e, "Exception occurred performing initial set up of continuous query and scan of existing items"); } finally { _log.LogInformation($"{context.Name} completed executing"); } }