Ejemplo n.º 1
0
        private Task Activate(
            DistributionLocations preferredLocation,
            Func <IEnumerable <DistributionSuggestion>, SelectedProposal> machineSelector,
            ICollectNotifications notifications,
            CancellationToken token,
            bool storeLocation)
        {
            {
                Debug.Assert(!Owner.IsClosed, "The owner should not be closed.");
                Debug.Assert(preferredLocation != DistributionLocations.None, "A distribution location should be specified.");
            }

            if (IsActivated)
            {
                return(Task.Factory.StartNew(
                           () => { },
                           token,
                           TaskCreationOptions.None,
                           new CurrentThreadTaskScheduler()));
            }

            if (m_IsActivating)
            {
                var onActivated = Observable.FromEventPattern <EventArgs>(
                    h => OnActivated += h,
                    h => OnActivated -= h)
                                  .Take(1);
                var onDeactivated = Observable.FromEventPattern <EventArgs>(
                    h => OnDeactivated += h,
                    h => OnDeactivated -= h)
                                    .Take(1);

                return(Observable.Amb(onActivated, onDeactivated)
                       .ToTask(token));
            }

            m_Diagnostics.Log(
                LevelToLog.Trace,
                HostConstants.LogPrefix,
                string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.DatasetProxy_LogMessage_ActivatingDataset_WithId,
                    Id));

            m_IsActivating = true;
            try
            {
                var request = new DatasetActivationRequest
                {
                    DatasetToActivate      = this,
                    PreferredLocations     = preferredLocation,
                    ExpectedLoadPerMachine = new ExpectedDatasetLoad
                    {
                        OnDiskSizeInBytes   = StoredAt.StoredSizeInBytes(),
                        InMemorySizeInBytes = StoredAt.StoredSizeInBytes(),
                        RelativeMemoryExpansionWhileRunning = 2.0,
                        RelativeOnDiskExpansionAfterRunning = 2.0,
                    },
                };

                var suggestedPlans = m_ConstructorArgs.DistributionPlanGenerator(request, token);
                var selection      = suggestedPlans.Select(plan => new DistributionSuggestion(plan));
                var selectedPlan   = machineSelector(selection);
                if (token.IsCancellationRequested || selectedPlan.WasSelectionCanceled)
                {
                    return(Task.Factory.StartNew(
                               () => { },
                               token,
                               TaskCreationOptions.None,
                               new CurrentThreadTaskScheduler()));
                }

                RaiseOnProgressOfCurrentAction(0, Resources.Progress_ActivatingDataset, false);
                var task             = selectedPlan.Plan.Accept(token, RaiseOnProgressOfCurrentAction);
                var continuationTask = task.ContinueWith(
                    t =>
                {
                    try
                    {
                        if (t.Exception != null)
                        {
                            m_Diagnostics.Log(
                                LevelToLog.Error,
                                HostConstants.LogPrefix,
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    Resources.DatasetProxy_LogMessage_FailedToActivateDataset_WithException,
                                    Id,
                                    t.Exception));

                            // Obviously not activated so ...
                            RaiseOnProgressOfCurrentAction(100, string.Empty, false);
                            RaiseOnDeactivated();

                            notifications.StoreNotification(Resources.Notifications_FailedToActivateDataset);
                            return;
                        }

                        var online   = t.Result;
                        m_Connection = online;
                        m_Connection.OnSwitchToEditMode      += HandleOnSwitchToEditMode;
                        m_Connection.OnSwitchToExecutingMode += HandleOnSwitchToExecutingMode;

                        m_DataProxy = m_ProxyBuilder(m_Connection);

                        if (storeLocation)
                        {
                            m_DistributionLocation.Current = selectedPlan.Plan.MachineToDistributeTo;
                        }

                        m_Diagnostics.Log(
                            LevelToLog.Trace,
                            HostConstants.LogPrefix,
                            string.Format(
                                CultureInfo.InvariantCulture,
                                Resources.DatasetProxy_LogMessage_DatasetActivationComplete_WithId,
                                Id));

                        RaiseOnActivated();
                    }
                    finally
                    {
                        m_IsActivating = false;
                    }
                },
                    TaskContinuationOptions.ExecuteSynchronously);

                return(continuationTask);
            }
            catch (Exception)
            {
                // Only clean this up if the whole thing falls over
                m_IsActivating = false;
                throw;
            }
        }