Set a period task in the IServerStartup Task but after a long time the task automatic stoped

48 views
Skip to first unread message

Tim Zhang

unread,
Sep 20, 2014, 10:16:04 PM9/20/14
to rav...@googlegroups.com
As the following code showing ,in my SendSlaveHeartbeatMessageServerTask I schedule another task using Timer
1.but after some time the scheduled task automatic stoped.
2.also the following error come out:
  "Raven.Web.ForwardToRavenRespondersFactory,Error,ShutdownDetector.Cancel error,"System.AggregateException: One or more errors occurred."

---------------------------------------------------------------------------------------------------------------------------------------------------------------
public class SendSlaveHeartbeatMessageServerTask : IServerStartupTask
    {
        private static readonly Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private ConcurrentDictionary<string, SendSlaveHeartbeatMessageTask> NsbrTasks
            = new ConcurrentDictionary<string, SendSlaveHeartbeatMessageTask>(StringComparer.OrdinalIgnoreCase);

        public void Execute(HttpServer server)
        {
            var disabled =
                WebAppConfigUtilities.GetConfiguredBooleanValue(RavenConstant.NsbrDisableTargetPluginHeartbeatTask);
            if (!disabled)
            {
                var databasesStr = WebAppConfigUtilities.GetConfiguredStringValue(RavenConstant.NsbrMonitoringDatabases);
                if (databasesStr != null)
                {
                    var databases = databasesStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var db in databases)
                    {
                        NsbrTasks.GetOrAdd(db, new SendSlaveHeartbeatMessageTask());
                    }
                    foreach (var item in NsbrTasks)
                    {
                        var currentTask = server.GetDatabaseInternal(item.Key);
                        if(currentTask!=null)
                        {
                            currentTask.ContinueWith(task =>
                            {
                                if (task != null)
                                    item.Value.Execute(task.Result);
                            });
                        }
                    }

                    logger.Info("SendSlaveHeartbeatMessageServerTask begin for databases:" + databasesStr);
                }

            }
        }
    }
------------------------------------------------------------------------------------------------------------------------------------------------------------------

public class SendSlaveHeartbeatMessageTask : IDisposable
    {
        private static readonly Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private Timer timer;
        public DocumentDatabase Database { get; set; }

        private volatile bool executing;

        #region Execute
        public void Execute(DocumentDatabase database)
        {
            if (string.IsNullOrEmpty(database.Name))  //except system db
                return;

            Database = database;

            var resentFrequencyInSeconds = Cofiguration.WebAppConfigUtilities.GetConfiguredIntValue(RavenConstant.NsbrHeartbeatFrenquencyInSeconds, 30);

            logger.Info("Initialized SendSlaveHeartbeatMessageTask, will scan for every {0} seconds", resentFrequencyInSeconds);

            timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(resentFrequencyInSeconds), TimeSpan.FromSeconds(resentFrequencyInSeconds));
        } 
        #endregion
        
        #region Dispose
        public void Dispose()
        {
            if (timer != null)
                timer.Dispose();
        } 
        #endregion

        #region TimerCallback
        private void TimerCallback(object state)
        {
            if (executing)
                return;

            executing = true;
            try
            {
                var metadata = new RavenJObject()
                {
                    {Constants.RavenEntityName,RavenJToken.FromObject(string.Format("{0}s",typeof(NsbrTestDocument).Name.ToLower()))}
                };
                Database.Put(RavenConstant.NsbrTestDocumentKey,null,
                    RavenJObject.FromObject(new NsbrTestDocument{ TestValue = "Write Test Data"}),metadata,null);

                Database.Get(RavenConstant.NsbrTestDocumentKey, null);

                GlobalBus.Bus.Send(
                    new RavenHostHeartbeatMessage { IsReadWriteWorks = true,
                        HostName = GlobalBus.HostName,
                        DbName = Database.Name,
                        IsMasterDb = false});
               
            }
            catch (Exception e)
            {
                logger.FatalException("SendSlaveHeartbeatMessageTask Error", e);
            }
            finally
            {
                executing = false;
            }
        } 
        #endregion

    }




--------------------------------------------------------------------------------------------------------------------------------------------------------------------

2014-09-20 10:13:09.7097,Raven.Web.ForwardToRavenRespondersFactory,Error,ShutdownDetector.Cancel error,"System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
   at System.Threading.Tasks.TaskCompletionSource`1.SetCanceled()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.CancellationCallbackInfo.ExecuteCallback()
   at System.Threading.CancellationTokenSource.CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments args)
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
   --- End of inner exception stack trace ---
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
   at Raven.Web.Utils.ShutdownDetector.Cancel() in c:\Builds\RavenDB-Stable\Raven.Web\Utils\ShutdownDetector.cs:line 102
---> (Inner Exception #0) System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
   at System.Threading.Tasks.TaskCompletionSource`1.SetCanceled()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.CancellationCallbackInfo.ExecuteCallback()
   at System.Threading.CancellationTokenSource.CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments args)
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)<---

Oren Eini (Ayende Rahien)

unread,
Sep 21, 2014, 6:57:12 AM9/21/14
to ravendb
You are running a task that access the database object directly, but that database object might be removed if it is considered idle.

What is it that you are trying to do?

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tim Zhang

unread,
Sep 21, 2014, 9:41:07 AM9/21/14
to rav...@googlegroups.com
I want send heatbeat message from ravendb databases to my monitor program.
To make sure my db is still working correctly.

在 2014年9月21日星期日UTC+8下午6时57分12秒,Oren Eini写道:

Oren Eini (Ayende Rahien)

unread,
Sep 21, 2014, 9:46:16 AM9/21/14
to ravendb
Do it vice versa

Chris Marisic

unread,
Sep 22, 2014, 10:58:01 AM9/22/14
to rav...@googlegroups.com
I believe Oren is stating you should have your monitoring program poll ravendb instead of ravendb using push notifications.

Kijana Woodard

unread,
Sep 22, 2014, 11:30:49 AM9/22/14
to rav...@googlegroups.com
You could do this without modifying the server.

Subscribe to change notifications on a "heartbeat document".
Have the monitor update the document periodically. 
The subscription should get fired.

But of course, you knew the database was up because you successfully wrote to the heartbeat document. ;-)
Reply all
Reply to author
Forward
0 new messages