public Task Activate( DistributionLocations preferredLocation, Func <IEnumerable <DistributionSuggestion>, SelectedProposal> machineSelector, CancellationToken token) { return(m_Dataset.Activate(preferredLocation, machineSelector, token)); }
/// <summary> /// Activates the dataset. /// </summary> /// <param name="preferredLocation"> /// Indicates a preferred machine location for the dataset to be distributed to. /// </param> /// <param name="machineSelector"> /// The function that selects the most suitable machine for the dataset to run on. /// </param> /// <remarks> /// Note that the <paramref name="preferredLocation"/> is /// only a suggestion. The loader may decide to ignore the suggestion if there is a distribution /// plan that is better suited to the contents of the dataset. /// </remarks> public void Activate( DistributionLocations preferredLocation, Func <DistributionSuggestionProxy[], DistributionSuggestionProxy> machineSelector) { var selector = new MachineSelectorFacade(machineSelector); m_Dataset.Activate(preferredLocation, selector); }
/// <summary> /// Activates the dataset in an asynchronous manner. /// </summary> /// <param name="preferredLocation"> /// Indicates a preferred machine location for the dataset to be distributed to. /// </param> /// <param name="machineSelector"> /// The function that selects the most suitable machine for the dataset to run on. /// </param> /// <param name="token">The token that is used to cancel the activation.</param> /// <remarks> /// Note that the <paramref name="preferredLocation"/> is /// only a suggestion. The activator may decide to ignore the suggestion if there is a distribution /// plan that is better suited to the contents of the dataset. /// </remarks> /// <returns> /// A <see cref="Task"/> that completes when the dataset is activated. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the project that owns this dataset has been closed. /// </exception> /// <exception cref="CannotActivateDatasetWithoutDistributionLocationException"> /// Thrown when the <paramref name="preferredLocation"/> is <see cref="DistributionLocations.None"/>. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown when <paramref name="machineSelector"/> is <see langword="null" />. /// </exception> public Task Activate( DistributionLocations preferredLocation, Func <IEnumerable <DistributionSuggestion>, SelectedProposal> machineSelector, CancellationToken token) { { Lokad.Enforce.With <ArgumentException>( !Owner.IsClosed, Resources.Exceptions_Messages_CannotUseProjectAfterClosingIt); Lokad.Enforce.With <CannotActivateDatasetWithoutDistributionLocationException>( preferredLocation != DistributionLocations.None, Resources.Exceptions_Messages_CannotActivateDatasetWithoutDistributionLocation); Lokad.Enforce.Argument(() => machineSelector); } return(Activate(preferredLocation, machineSelector, m_Notifications, token, true)); }
/// <summary> /// Activates the dataset. /// </summary> /// <param name="preferredLocation"> /// Indicates a preferred machine location for the dataset to be distributed to. /// </param> /// <param name="machineSelector"> /// The function that selects the most suitable machine for the dataset to run on. /// </param> /// <remarks> /// Note that the <paramref name="preferredLocation"/> is /// only a suggestion. The loader may decide to ignore the suggestion if there is a distribution /// plan that is better suited to the contents of the dataset. /// </remarks> public void Activate( DistributionLocations preferredLocation, MachineSelectorFacade machineSelector) { Func <IEnumerable <DistributionSuggestion>, SelectedProposal> func = enumerable => { var selection = enumerable.ToList(); var proxies = selection.Select(s => new DistributionSuggestionProxy(s)).ToArray(); var result = machineSelector.SelectFrom(proxies); var selectedPlan = selection.Find(s => s.Plan.MachineToDistributeTo.Equals(result.MachineToDistributeTo)); return(new SelectedProposal(selectedPlan.Plan)); }; // CancellationToken is not serializable hence ... var token = new CancellationTokenSource(); m_Dataset.Activate(preferredLocation, func, token.Token) .ContinueWith(t => token.Dispose()); }
private static IEnumerable <DatasetActivationProposal> OrderProposals( ExpectedDatasetLoad load, DistributionLocations preferedLocations, IEnumerable <Tuple <EndpointId, IDatasetActivationCommands> > usableNodes, CancellationToken token) { var loadingProposals = new Queue <Task <DatasetActivationProposal> >(); bool shouldLoad = ShouldLoadDistributed(preferedLocations); foreach (var pair in usableNodes) { if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } if (shouldLoad) { try { var result = pair.Item2.ProposeFor(load); loadingProposals.Enqueue(result); } catch (CommandInvocationFailedException) { // Chances are the endpoint just disappeared // so we just ignore it and move on. } } } while (loadingProposals.Count > 0) { if (token.IsCancellationRequested) { // Just abandon any tasks that were running but not finished token.ThrowIfCancellationRequested(); } var task = loadingProposals.Dequeue(); if (!task.IsCompleted) { if (loadingProposals.Count > 1) { loadingProposals.Enqueue(task); continue; } else { try { task.Wait(); } catch (AggregateException) { continue; } } } if (task.IsCanceled || task.IsFaulted) { // Get the exception so that the task doesn't throw in // the finalizer. Don't do anything with this though // because we don't really care. var exception = task.Exception; continue; } var proposal = task.Result; if (proposal.IsAvailable) { yield return(proposal); } } }
private static bool ShouldLoadDistributed(DistributionLocations preferedLocations) { return(((preferedLocations & DistributionLocations.DistributedOnCluster) == DistributionLocations.DistributedOnCluster) || ((preferedLocations & DistributionLocations.DistributedOnPeerToPeer) == DistributionLocations.DistributedOnPeerToPeer)); }
private static bool ShouldLoadDistributed(DistributionLocations preferedLocations) { return ((preferedLocations & DistributionLocations.DistributedOnCluster) == DistributionLocations.DistributedOnCluster) || ((preferedLocations & DistributionLocations.DistributedOnPeerToPeer) == DistributionLocations.DistributedOnPeerToPeer); }
private static IEnumerable<DatasetActivationProposal> OrderProposals( ExpectedDatasetLoad load, DistributionLocations preferedLocations, IEnumerable<Tuple<EndpointId, IDatasetActivationCommands>> usableNodes, CancellationToken token) { var loadingProposals = new Queue<Task<DatasetActivationProposal>>(); bool shouldLoad = ShouldLoadDistributed(preferedLocations); foreach (var pair in usableNodes) { if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } if (shouldLoad) { try { var result = pair.Item2.ProposeFor(load); loadingProposals.Enqueue(result); } catch (CommandInvocationFailedException) { // Chances are the endpoint just disappeared // so we just ignore it and move on. } } } while (loadingProposals.Count > 0) { if (token.IsCancellationRequested) { // Just abandon any tasks that were running but not finished token.ThrowIfCancellationRequested(); } var task = loadingProposals.Dequeue(); if (!task.IsCompleted) { if (loadingProposals.Count > 1) { loadingProposals.Enqueue(task); continue; } else { try { task.Wait(); } catch (AggregateException) { continue; } } } if (task.IsCanceled || task.IsFaulted) { // Get the exception so that the task doesn't throw in // the finalizer. Don't do anything with this though // because we don't really care. var exception = task.Exception; continue; } var proposal = task.Result; if (proposal.IsAvailable) { yield return proposal; } } }
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; } }