Order of state checking

102 views
Skip to first unread message

zam...@gmail.com

unread,
Mar 19, 2013, 2:50:25 PM3/19/13
to nappu...@googlegroups.com
Hi

I have a Windows Service that kick off a job based on schedule.
We wanted to add silent selft updates and have been trying to incorporate NAppUpdate for this purpose.

But after reading the blog post and looking at the AutoUpdate sample mentioned in it I am a bit confused as to what is the proper order of checking UpdateManager State(s).

  • In the example mentioned, why is the check for Rollback being done only after determining that update process is already taking place? 
  • With respect to rollback, Is it better to do updates at the start of the app/job or just before exit/end of the job?

I have recompiled NAppUpdate from source (targeting .NET 4.5) and have attempted to recreate the example (current one relies on framework returning true/false which is no longer the case)...
All I am looking for is synchronous, blocking, simple, and silent update for console app (or service), and I am not sure if I have it right (the 3 examples are all forms based (WinForms or WPF)...

Can someone please explain if I have this right...

Thanks - here is the relevant method:


private static void AutoUpdate(IUpdateSource updateSource)
{
    if (updateSource == null)
    {
        throw new ArgumentNullException("updateSource", "Update source cannot be null!");
    }
    try
    {
        // ------------------------------------------------------------
        // 1. initialize & verify
        //
        // set source
        UpdateManager.Instance.UpdateSource = updateSource;
        // Only check for updates if we haven't done so already
        if (UpdateManager.Instance.State != UpdateManager.UpdateProcessState.NotChecked)
        {
            //NOTE: why rollback check only after != NotChecked?
            if (UpdateManager.Instance.State == UpdateManager.UpdateProcessState.RollbackRequired)
            {
                UpdateManager.Instance.RollbackUpdates();
            }
            else
            {
                return;
            }
        }
        // ------------------------------------------------------------
        // 2. check for updates
        //
        UpdateManager.Instance.CheckForUpdates(); // NOTE: should we check the status == Checked first?
        if (UpdateManager.Instance.UpdatesAvailable == 0)
        {
            return;
        }
        // ------------------------------------------------------------
        // 3. prepare updates (download, stage, etc, etc)
        //
        UpdateManager.Instance.PrepareUpdates(); // NOTE: should we check the status == Prepared first?
        // ------------------------------------------------------------
        // 4. apply updates
        //
        UpdateManager.Instance.ApplyUpdates(false, true, false); // relaunchApplication, updaterDoLogging, updaterShowConsole

        if (UpdateManager.Instance.State == UpdateManager.UpdateProcessState.AppliedSuccessfully)
        {
            Logger.Info(CultureInfo.InvariantCulture, m => m("4a. Update successful! [state: \"{0}\"]", UpdateManager.Instance.State));
        }
        else
        {
            Logger.Warn(CultureInfo.InvariantCulture, m => m("4b. Update was *not* successful! [state: \"{0}\"]", UpdateManager.Instance.State));
        }
    }
    catch (NAppUpdateException e)
    {
        Logger.Error(CultureInfo.InvariantCulture, m => m("Update failed! [last state: \"{0}\"]", UpdateManager.Instance.State), e);
        //NOTE: should we Rollback on exception?
    }
    catch (Exception e)
    {
        Logger.Error(CultureInfo.InvariantCulture, m => m("Exception occurred during update process! [last state: \"{0}\"]", UpdateManager.Instance.State), e);
        //NOTE: should we Rollback on exception?
    }
    finally
    {
        Logger.Info(CultureInfo.InvariantCulture, m => m("Dumping log file & cleaning up..."));
        UpdateManager.Instance.Logger.Dump();
        UpdateManager.Instance.CleanUp();
    }
}

Itamar Syn-Hershko

unread,
Mar 20, 2013, 6:26:11 PM3/20/13
to nappu...@googlegroups.com
This seems about right, although if you are synchronous you are probably doing too much error checking.

Re rollbacks - not sure I understand the question. I'd check and prepare the updates when the service goes up, and schedule the call to Apply for when it exits


--
You received this message because you are subscribed to the Google Groups "NAppUpdate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nappupdate+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

zam...@gmail.com

unread,
Mar 20, 2013, 7:06:39 PM3/20/13
to nappu...@googlegroups.com
Re rollbacks

I was referring to this piece of code:
Is it required or desirable to check for rollback only when state is != NotChecked

Itamar Syn-Hershko

unread,
Mar 21, 2013, 4:30:37 AM3/21/13
to nappu...@googlegroups.com
Rollback is only applicable when ApplyUpdates is called and failed

zam...@gmail.com

unread,
Mar 21, 2013, 8:50:49 AM3/21/13
to nappu...@googlegroups.com
So what would be the appropriate place to call rollback? 
In an try block?

There is only one exception "NAppUpdateException" so how we detect that ApplyUpdates() failed?
for hotswap updates it would be easy to check if state !=  UpdateManager.UpdateProcessState.AppliedSuccessfully and do the rollback.
But for cold updates and on exceptions occurring what would be the best approach?

Itamar Syn-Hershko

unread,
Mar 22, 2013, 8:29:37 AM3/22/13
to nappu...@googlegroups.com
This depends. If you have no cold updates to perform, this is simple - if one update fails ApplyUpdates will rollback everything itself. This can be improved by splitting updates to task groups, but thats still a TODO.

If there are cold updates and one of them fails, then currently the state the app is in isn't well-defined. I'm aware of this and thought of solving it by the state restoration we are working on. Following thoughts originating on the other thread, I'm thinking now of completely removing the notion of cold updates and doing everything in one sweep. This will greately simplify a lot of things, this issue included.
Reply all
Reply to author
Forward
0 new messages