Example #1
0
        /// <summary>
        /// Initiates a retry for specified event type.
        /// </summary>
        /// <param name="ex">Exception causing retry.</param>
        /// <param name="eventType">Event type to retry.</param>
        private void RetrySynchronizedEvent(Exception ex, int eventType)
        {
            if (m_disposed)
            {
                return;
            }

            // A retry is only being initiating for basic file I/O or locking errors - monitor these failures occurring
            // in quick succession so that retry activity is not allowed to go on forever...
            if (DateTime.UtcNow.Ticks - m_lastRetryTime > (long)Ticks.FromMilliseconds(m_retryTimer.Interval * m_maximumRetryAttempts))
            {
                // Significant time has passed since last retry, so we reset counter
                m_retryCount    = 0;
                m_lastRetryTime = DateTime.UtcNow.Ticks;
            }
            else
            {
                m_retryCount++;

                if (m_retryCount >= m_maximumRetryAttempts)
                {
                    throw new UnauthorizedAccessException("Failed to " + (eventType == WriteEvent ? "write data to " : "read data from ") + m_fileName + " after " + m_maximumRetryAttempts + " attempts: " + ex.Message, ex);
                }
            }

            // Technically the inter-process mutex will handle serialized access to the file, but if the OS or other process
            // not participating with the mutex has the file locked, all we can do is queue up a retry for this event.
            lock (m_retryQueue)
            {
                m_retryQueue[eventType] = true;
            }
            m_retryTimer.Start();
        }
 void SetFlushTimer()
 {
     if (flushTimer == null)
     {
         int flushSkew = Ticks.ToMilliseconds(Math.Min(flushTimeout / 10, Ticks.FromMilliseconds(maxFlushSkew)));
         flushTimer = new IOThreadTimer(new Action <object>(OnFlushTimer), null, true, flushSkew);
     }
     flushTimer.Set(Ticks.ToTimeSpan(flushTimeout));
 }
Example #3
0
 private void Initialize()
 {
     RetrieveSettingsFromIsolatedStorage(false);
     m_timeStampList          = new ConcurrentQueue <string>();
     m_yAxisDataCollection    = new ConcurrentDictionary <Guid, ConcurrentQueue <double> >();
     m_yAxisBindingCollection = new ConcurrentDictionary <Guid, EnumerableDataSource <double> >();
     m_lineGraphCollection    = new ConcurrentDictionary <Guid, LineGraph>();
     m_selectedMeasurements   = new ConcurrentDictionary <Guid, RealTimeMeasurement>();
     m_displayedMeasurement   = new ObservableCollection <RealTimeMeasurement>();
     m_displayedMeasurement.CollectionChanged += m_displayedMeasurement_CollectionChanged;
     m_restartConnectionCycle = true;
     m_xAxisDataCollection    = new int[m_numberOfDataPointsToPlot];
     m_refreshRate            = Ticks.FromMilliseconds(m_chartRefreshInterval);
     TextBlockMeasurementRefreshInterval.Text = m_measurementsDataRefreshInterval.ToString();
     TextBlockStatisticsRefreshInterval.Text  = m_statisticsDataRefershInterval.ToString();
     TextBoxProcessInterval.Text = "33";
 }
Example #4
0
        private void PrepareConnect(Uri remoteUri, TimeSpan timeout, out string resolvedAddress, out BackoffTimeoutHelper backoffHelper)
        {
            TimeSpan span;

            PipeUri.Validate(remoteUri);
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(TraceEventType.Information, 0x4002a, System.ServiceModel.SR.GetString("TraceCodeInitiatingNamedPipeConnection"), new StringTraceRecord("Uri", remoteUri.ToString()), this, null);
            }
            resolvedAddress = GetPipeName(remoteUri);
            if (timeout >= TimeSpan.FromMilliseconds(300.0))
            {
                span = TimeoutHelper.Add(timeout, TimeSpan.Zero - TimeSpan.FromMilliseconds(150.0));
            }
            else
            {
                span = Ticks.ToTimeSpan((Ticks.FromMilliseconds(150) / 2L) + 1L);
            }
            backoffHelper = new BackoffTimeoutHelper(span, TimeSpan.FromMinutes(5.0));
        }
Example #5
0
        /// <summary>Event handler for service started operation.</summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event arguments.</param>
        /// <remarks>
        /// Time-series framework uses this handler to handle initialization of system objects.
        /// </remarks>
        protected override void ServiceStartedHandler(object sender, EventArgs e)
        {
            base.ServiceStartedHandler(sender, e);

            CategorizedSettingsElementCollection systemSettings = ConfigurationFile.Current.Settings["systemSettings"];

            if (systemSettings["eDNAGrafanaControllerEnabled", true]?.Value.ParseBoolean() ?? true)
            {
                ServiceHelper.ClientRequestHandlers.Add(new ClientRequestHandler("eDNARefreshMetadata", "Refreshes eDNA metadata.", RefreshMetaDataHandler, new[] { "eDNARefresh", "RefresheDNAMetadata" }));
            }

            if (!Model.Global.GrafanaServerInstalled)
            {
                return;
            }

            // Kick off a thread to monitor for when Grafana server has been properly
            // initialized so that initial user synchronization process can proceed
            new Thread(() =>
            {
                try
                {
                    const int DefaultInitializationTimeout = GrafanaAuthProxyController.DefaultInitializationTimeout;

                    // Access settings from "systemSettings" category in configuration file
                    CategorizedSettingsElementCollection grafanaHosting = ConfigurationFile.Current.Settings["grafanaHosting"];

                    // Make sure needed settings exist
                    grafanaHosting.Add("InitializationTimeout", DefaultInitializationTimeout, "Defines the timeout, in seconds, for the Grafana system to initialize.");

                    // Get settings as currently defined in configuration file
                    int initializationTimeout = grafanaHosting["InitializationTimeout"].ValueAs(DefaultInitializationTimeout);
                    DateTime startTime        = DateTime.UtcNow;
                    bool timeout = false;

                #if DEBUG
                    // Debugging adds run-time overhead, provide more time for initialization
                    initializationTimeout *= 3;
                    int attempts           = 0;
                #endif

                    // Give initialization - which includes starting Grafana server process - a chance to start
                    while (!GrafanaAuthProxyController.ServerIsResponding())
                    {
                        // Stop attempts after timeout has expired
                        if ((DateTime.UtcNow - startTime).TotalSeconds >= initializationTimeout)
                        {
                            timeout = true;
                            break;
                        }

                        Thread.Sleep(500);

                    #if DEBUG
                        if (++attempts % 4 == 0)
                        {
                            DisplayStatusMessage($"DEBUG: Awaiting Grafana initialization, {attempts:N0} attempts so far...", UpdateType.Warning);
                        }
                    #endif
                    }

                    if (timeout)
                    {
                        DisplayStatusMessage($"WARNING: Service started handler reported timeout awaiting Grafana initialization. Timeout configured as {Ticks.FromMilliseconds(initializationTimeout).ToElapsedTimeString(2)}.", UpdateType.Warning);
                    }
                }
                catch (Exception ex)
                {
                    LogException(new InvalidOperationException($"Failed while checking for Grafana server initialization: {ex.Message}", ex));
                }
                finally
                {
                    GrafanaAuthProxyController.InitializationComplete();
                }
            })
            {
                IsBackground = true
            }
            .Start();
        }
 private void SetFlushTimer()
 {
     if (this.flushTimer == null)
     {
         int maxSkewInMilliseconds = Ticks.ToMilliseconds(Math.Min(this.flushTimeout / 10L, Ticks.FromMilliseconds(100)));
         this.flushTimer = new IOThreadTimer(new Action <object>(this.OnFlushTimer), null, true, maxSkewInMilliseconds);
     }
     this.flushTimer.Set(Ticks.ToTimeSpan(this.flushTimeout));
 }
        private void ExecuteExports()
        {
            byte[] fileData = m_fileData;

            if (m_enabled && (object)fileData != null && m_exportDestinations.Count > 0)
            {
                string              fileName     = null;
                ExportState[]       exportStates = null;
                ExportDestination[] destinations;

                try
                {
                    //  Get a temporary file name
                    fileName = Path.GetTempFileName();

                    // Export data to the temporary file
                    File.WriteAllBytes(fileName, fileData);

                    lock (m_exportDestinationsLock)
                    {
                        // Cache a local copy of export destinations to reduce lock time
                        destinations = m_exportDestinations.ToArray();
                    }

                    // Define a new export state for each export destination
                    exportStates = new ExportState[destinations.Length];

                    for (int i = 0; i < exportStates.Length; i++)
                    {
                        exportStates[i] = new ExportState
                        {
                            SourceFileName      = fileName,
                            DestinationFileName = destinations[i].DestinationFile
                        };
                    }

                    // Spool threads to attempt copy of export files
                    for (int i = 0; i < destinations.Length; i++)
                    {
                        ThreadPool.QueueUserWorkItem(CopyFileToDestination, exportStates[i]);
                    }

                    // Wait for exports to complete - even if user specifies to wait indefinitely spooled copy routines
                    // will eventually return since there is a specified maximum retry count
                    if (!exportStates.Select(exportState => exportState.WaitHandle).WaitAll(m_exportTimeout))
                    {
                        // Exports failed to complete in specified allowed time, set timeout flag for each export state
                        Array.ForEach(exportStates, exportState => exportState.Timeout = true);
                        OnStatusMessage("Timed out attempting export, waited for {0}.", Ticks.FromMilliseconds(m_exportTimeout).ToElapsedTimeString(2).ToLower());
                    }
                }
                catch (Exception ex)
                {
                    OnProcessException(new InvalidOperationException($"Exception encountered during export preparation: {ex.Message}", ex));
                }
                finally
                {
                    // Dispose the export state wait handles
                    if ((object)exportStates != null)
                    {
                        foreach (ExportState exportState in exportStates)
                        {
                            exportState.Dispose();
                        }
                    }

                    // Delete the temporary file - wait for the specified retry time in case the export threads may still be trying
                    // their last copy attempt. This is important if the timeouts are synchronized and there is one more export
                    // about to be attempted before the timeout flag is checked.
                    new Action(() => DeleteTemporaryFile(fileName)).DelayAndExecute(m_retryDelayInterval);
                }
            }
        }
        private static void SynchronizeUsers()
        {
            using (Logger.SuppressFirstChanceExceptionLogMessages())
            {
                Dictionary <string, string[]> securityContext = s_latestSecurityContext;

                if (securityContext is null)
                {
                    return;
                }

                // Skip user synchronization if security context has not changed
                if (!s_manualSynchronization && SecurityContextsAreEqual(securityContext, s_lastSecurityContext))
                {
                    return;
                }

                s_manualSynchronization = false;
                Interlocked.Exchange(ref s_lastSecurityContext, securityContext);

                // Give initialization - which includes starting Grafana server process - a chance to complete
                if (!s_initializationWaitHandle.Wait(s_initializationTimeout))
                {
                    OnStatusMessage($"WARNING: Grafana user synchronization reported timeout awaiting Grafana initialization. Timeout configured as {Ticks.FromMilliseconds(s_initializationTimeout).ToElapsedTimeString(2)}.");
                }

                // Lookup Grafana Administrative user
                if (!LookupUser(s_adminUser, out UserDetail userDetail, out string message))
                {
                    OnStatusMessage($"WARNING: Failed to synchronize Grafana users, cannot find Grafana Administrator \"{s_adminUser}\": {message}");
                    return;
                }

                // Get user list for target organization
                OrgUserDetail[] organizationUsers = GetOrganizationUsers(s_organizationID, out message);

                if (!string.IsNullOrEmpty(message))
                {
                    OnStatusMessage($"Issue retrieving user list for default organization: {message}");
                }

                // Make sure Grafana Administrator has an admin role in the default organization
                bool success = organizationUsers.Any(user => user.userId == userDetail.id) ?
                               UpdateUserOrganizationalRole(s_organizationID, userDetail.id, "Admin", out message) :
                               AddUserToOrganization(s_organizationID, s_adminUser, "Admin", out message);

                if (!success)
                {
                    OnStatusMessage($"Issue validating organizational admin role for Grafana Administrator \"{s_adminUser}\" - Grafana user synchronization may not succeed: {message}");
                }

                foreach (KeyValuePair <string, string[]> item in securityContext)
                {
                    string   userName    = item.Key;
                    string[] roles       = item.Value;
                    bool     createdUser = false;

                    if (userName.Equals("_logout", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    // Check if user exists
                    if (!LookupUser(userName, out userDetail, out message))
                    {
                        createdUser = CreateUser(userName, s_organizationID, out userDetail, out message);
                        OnStatusMessage($"Encountered new user \"{userName}\": {message}");
                    }

                    if (userDetail.id == 0)
                    {
                        continue;
                    }

                    // Update user's Grafana admin role status if needed
                    bool userIsGrafanaAdmin = UserIsGrafanaAdmin(roles);

                    if (userDetail.isGrafanaAdmin != userIsGrafanaAdmin)
                    {
                        try
                        {
                            JObject content = JObject.FromObject(new
                            {
                                isGrafanaAdmin = userIsGrafanaAdmin
                            });

                            message = CallAPIFunction(HttpMethod.Put, $"{s_baseUrl}/api/admin/users/{userDetail.id}/permissions", content.ToString()).Result.message;
                        }
                        catch (Exception ex)
                        {
                            message = ex.Message;
                        }

                        if (!message.Equals("User permissions updated", StringComparison.OrdinalIgnoreCase))
                        {
                            OnStatusMessage($"Issue updating permissions for user \"{userName}\": {message}");
                        }
                    }

                    // Attempt to lookup user in default organization
                    OrgUserDetail orgUserDetail = organizationUsers.FirstOrDefault(user => user.userId == userDetail.id);

                    // Get user's organizational role: Admin / Editor / Viewer
                    string organizationalRole = TranslateRole(roles);

                    // Update user's organizational status / role as needed
                    if (orgUserDetail is null && !createdUser)
                    {
                        success = AddUserToOrganization(s_organizationID, userName, organizationalRole, out message);
                    }