예제 #1
0
        /// <summary>
        /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use.
        /// Builds all the stuff up, constructs the DownloaderManager.  Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it.
        /// **NOTE:  this follows a variant of the Builder Pattern, where we delegate constuction of a complex object.
        /// could also have been in a separate Builder or Factory class but small enough to put here.
        /// </summary>
        /// <param name="application">the name of the Updater target application</param>
        /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns>
        private DnldMgrHolder SetupDownloadManager(ApplicationConfiguration application)
        {
            DownloaderManager dnldMgr = null;

            //  create an instance of a Downloader for DownloaderManager to use:
            IDownloader downloader = DownloaderFactory.Create(UpdaterConfiguration.Instance);

            //  create instance of Validator for DownloaderManager to use:
            IValidator validator = ValidatorFactory.Create(UpdaterConfiguration.Instance);

            //  populate application jobentry for shared
            DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry(application.Name, Guid.Empty, JobStatus.Ready);

            //  create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr
            ManualResetEvent mustStop = new ManualResetEvent(false);

            //  create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly:
            BadExitCallback badExitCbk = new BadExitCallback(this.RestartUpdater);

            //  create the download manager, feed it our instance of actual downloader
            dnldMgr = new DownloaderManager(downloader, validator, dnldJob, mustStop, badExitCbk);

            //  create the thread that this dnldMgr + its other objects will run on
            Thread dnldThread = new Thread(new ThreadStart(dnldMgr.RunDownloader));

            dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString();

            //  create new holder struct for thread + dnldmgr
            DnldMgrHolder holder = new DnldMgrHolder(dnldThread, dnldMgr);

            #region    Event Registrations

            //  ***  NOTE:  we facade all these underlying events through this class to
            //  ***			a)  avoid exposing dnldMgr class
            //  ***			b)  so later if we choose to use a better threading model--that is, NOT allow
            //  ***				our threads to "venture outside" and possibly dawdle out there (get blocked for instance)
            //  ***				then it will be easy to spawn a dedicated eventing thread in here.
            //  ***  NOTE:  IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events.
            //  ***  the sinking app will have to distinguish which app fired which event from the event args

            //  REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so
            //  we shuttle its events through this class
            dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler(OnServerManifestDownloaded);
            dnldMgr.UpdateAvailable          += new UpdaterActionEventHandler(OnUpdateAvailable);
            dnldMgr.DownloadStarted          += new UpdaterActionEventHandler(OnDownloadStarted);
            dnldMgr.DownloadCompleted        += new UpdaterActionEventHandler(OnDownloadCompleted);
            dnldMgr.ManifestValidated        += new UpdaterActionEventHandler(OnManifestValidated);
            dnldMgr.ManifestValidationFailed += new UpdaterActionEventHandler(OnManifestValidationFailed);
            dnldMgr.FilesValidated           += new UpdaterActionEventHandler(OnFilesValidated);
            dnldMgr.FilesValidationFailed    += new UpdaterActionEventHandler(OnFilesValidationFailed);

            #endregion

            //  return the packaged DnldMgr
            return(holder);
        }
예제 #2
0
        /// <summary>
        /// Only constructor for DownloaderManager.  All parameters required for proper function.
        /// </summary>
        /// <param name="downloader">instance of IDownloader implementation</param>
        /// <param name="validator">instance of IValidator implementation</param>
        /// <param name="downloadJob">encapsulation of Job information in DownloadJobStatusEntry instance, such as app name job status job id</param>
        /// <param name="mustStop">an MRE used by Updater to tell this object it must clean up and leave or be Interrupt()ed</param>
        /// <param name="badExitCbk">delegate instance this class will call on on unrecoverable error, such as an unanticpated exception that compromises too badly to contine</param>
        public DownloaderManager
        (
            IDownloader downloader,
            IValidator validator,
            DownloadJobStatusEntry downloadJob,
            ManualResetEvent mustStop,
            BadExitCallback badExitCbk
        )
        {
            _downloader       = downloader;
            _validator        = validator;
            _dnldJob          = downloadJob;
            _mustStopUpdating = mustStop;

            //  using our app's name, look up the application object (ApplicationConfiguration) in array of applications--
            //  since WE are working on one, but there may be many
            _application = UpdaterConfiguration.Instance[_dnldJob.ApplicationName];

            //  set out internal delegate instance of BadExitCallback.
            //  this is the function pointer we'll use to notify UpdaterManager of really poor exits (fatal exceptions etc.)
            _badExitCbk = badExitCbk;
        }
        /// <summary>
        /// Only constructor for DownloaderManager.  All parameters required for proper function.
        /// </summary>
        /// <param name="downloader">instance of IDownloader implementation</param>
        /// <param name="validator">instance of IValidator implementation</param>
        /// <param name="downloadJob">encapsulation of Job information in DownloadJobStatusEntry instance, such as app name job status job id</param>
        /// <param name="mustStop">an MRE used by Updater to tell this object it must clean up and leave or be Interrupt()ed</param>
        /// <param name="badExitCbk">delegate instance this class will call on on unrecoverable error, such as an unanticpated exception that compromises too badly to contine</param>
        public DownloaderManager( 
            IDownloader downloader,
            IValidator validator,
            DownloadJobStatusEntry downloadJob,
            ManualResetEvent mustStop,
            BadExitCallback badExitCbk
            )
        {
            _downloader = downloader;
            _validator = validator;
            _dnldJob = downloadJob;
            _mustStopUpdating = mustStop;

            //  using our app's name, look up the application object (ApplicationConfiguration) in array of applications--
            //  since WE are working on one, but there may be many
            _application = UpdaterConfiguration.Instance[ _dnldJob.ApplicationName ];

            //  set out internal delegate instance of BadExitCallback.
            //  this is the function pointer we'll use to notify UpdaterManager of really poor exits (fatal exceptions etc.)
            _badExitCbk = badExitCbk;
        }
        /// <summary>
        /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use.
        /// Builds all the stuff up, constructs the DownloaderManager.  Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it.
        /// **NOTE:  this follows a variant of the Builder Pattern, where we delegate constuction of a complex object.
        /// could also have been in a separate Builder or Factory class but small enough to put here.
        /// </summary>
        /// <param name="application">the name of the Updater target application</param>
        /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns>
        private DnldMgrHolder SetupDownloadManager( ApplicationConfiguration application )
        {
            DownloaderManager dnldMgr = null;

            //  create an instance of a Downloader for DownloaderManager to use:
            IDownloader downloader = DownloaderFactory.Create( UpdaterConfiguration.Instance );

            //  create instance of Validator for DownloaderManager to use:
            IValidator validator = ValidatorFactory.Create( UpdaterConfiguration.Instance );

            //  populate application jobentry for shared
            DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry( application.Name, Guid.Empty, JobStatus.Ready );

            //  create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr
            ManualResetEvent mustStop = new ManualResetEvent( false );

            //  create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly:
            BadExitCallback badExitCbk = new BadExitCallback( this.RestartUpdater );

            //  create the download manager, feed it our instance of actual downloader
            dnldMgr = new DownloaderManager( downloader, validator, dnldJob, mustStop, badExitCbk );

            //  create the thread that this dnldMgr + its other objects will run on
            Thread dnldThread = new Thread( new ThreadStart( dnldMgr.RunDownloader ) );
            dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString();

            //  create new holder struct for thread + dnldmgr
            DnldMgrHolder holder = new DnldMgrHolder( dnldThread, dnldMgr );

            #region    Event Registrations

            //  ***  NOTE:  we facade all these underlying events through this class to
            //  ***			a)  avoid exposing dnldMgr class
            //  ***			b)  so later if we choose to use a better threading model--that is, NOT allow
            //  ***				our threads to "venture outside" and possibly dawdle out there (get blocked for instance)
            //  ***				then it will be easy to spawn a dedicated eventing thread in here.
            //  ***  NOTE:  IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events.
            //  ***  the sinking app will have to distinguish which app fired which event from the event args

            //  REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so
            //  we shuttle its events through this class
            dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler( OnServerManifestDownloaded );
            dnldMgr.UpdateAvailable += new UpdaterActionEventHandler( OnUpdateAvailable );
            dnldMgr.DownloadStarted += new UpdaterActionEventHandler( OnDownloadStarted );
            dnldMgr.DownloadCompleted += new UpdaterActionEventHandler( OnDownloadCompleted );
            dnldMgr.ManifestValidated +=new UpdaterActionEventHandler( OnManifestValidated );
            dnldMgr.ManifestValidationFailed +=new UpdaterActionEventHandler( OnManifestValidationFailed );
            dnldMgr.FilesValidated +=new UpdaterActionEventHandler( OnFilesValidated );
            dnldMgr.FilesValidationFailed +=new UpdaterActionEventHandler( OnFilesValidationFailed );

            #endregion

            //  return the packaged DnldMgr
            return holder;
        }