Exemple #1
0
        /// <summary>
        /// Sends a data stream to the given endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint to which the data should be send.</param>
        /// <param name="dataText">The text.</param>
        public void SendDataTo(EndpointId endpoint, string dataText)
        {
            if (m_Commands.HasCommandFor(endpoint, typeof(ITestCommandSet)))
            {
                var path = Path.Combine(Assembly.GetExecutingAssembly().LocalDirectoryPath(), Path.GetRandomFileName());
                using (var writer = new StreamWriter(path, false))
                {
                    writer.Write(dataText);
                }

                var token = m_Uploads.Register(path);

                var commands = m_Commands.CommandsFor <ITestCommandSet>(endpoint);
                commands.StartDownload(token);
            }
        }
        /// <summary>
        /// Finds the plug-in container (i.e. the assembly) that matches the given name and prepares it for uploading to
        /// a dataset application.
        /// </summary>
        /// <param name="name">The name of the assembly that contains the plug-in.</param>
        /// <returns>A task that will finish once the assembly is queued and ready for upload.</returns>
        public Task <UploadToken> PreparePluginContainerForTransfer(AssemblyName name)
        {
            return(Task <UploadToken> .Factory.StartNew(
                       () =>
            {
                if (!m_Configuration.HasValueFor(CoreConfigurationKeys.PluginLocation))
                {
                    throw new FileNotFoundException();
                }

                var pluginDirectories = m_Configuration.Value <List <string> >(CoreConfigurationKeys.PluginLocation);
                var assemblyFilePath = FindAssembly(name, pluginDirectories);

                if (assemblyFilePath == null)
                {
                    throw new FileNotFoundException();
                }

                return m_UploadCollection.Register(assemblyFilePath.FullName);
            }));
        }
Exemple #3
0
        /// <summary>
        /// Takes the set of distribution plans and loads the given datasets onto the specified machines.
        /// </summary>
        /// <param name="planToImplement">The distribution plan that should be implemented.</param>
        /// <param name="token">The token used to indicate cancellation of the task.</param>
        /// <param name="progressReporter">The action that handles the reporting of progress.</param>
        /// <returns>
        /// A set of objects which allow act as proxies for the loaded datasets.
        /// </returns>
        public Task <DatasetOnlineInformation> ImplementPlan(
            DistributionPlan planToImplement,
            CancellationToken token,
            Action <int, string, bool> progressReporter)
        {
            Func <DatasetOnlineInformation> result =
                () =>
            {
                IDatasetActivationCommands activationCommands;
                lock (m_Lock)
                {
                    if (!m_ActivatorCommands.ContainsKey(planToImplement.Proposal.Endpoint))
                    {
                        throw new EndpointNotContactableException(planToImplement.Proposal.Endpoint);
                    }

                    activationCommands = m_ActivatorCommands[planToImplement.Proposal.Endpoint];
                }

                // We shouldn't have to load the TCP channel at this point because that channel would have
                // been loaded when the loaders broadcast their message indicating that they exist.
                var info         = m_CommunicationLayer.LocalConnectionFor(ChannelType.TcpIP);
                var endpointTask = activationCommands.Activate(info.Item1, ChannelType.TcpIP, info.Item2, planToImplement.DistributionFor.Id);
                endpointTask.Wait();

                var endpoint   = endpointTask.Result;
                var resetEvent = new AutoResetEvent(false);
                var commandAvailabilityNotifier =
                    Observable.FromEventPattern <CommandSetAvailabilityEventArgs>(
                        h => m_CommandHub.OnEndpointSignedIn += h,
                        h => m_CommandHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1)
                    .Subscribe(
                        args =>
                {
                    resetEvent.Set();
                });

                using (commandAvailabilityNotifier)
                {
                    if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint))
                    {
                        resetEvent.WaitOne();
                    }
                }

                EventHandler <ProgressEventArgs> progressHandler =
                    (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors);
                var notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint);
                notifications.OnProgress += progressHandler;
                try
                {
                    // Store the file
                    var file        = planToImplement.DistributionFor.StoredAt.AsFile();
                    var uploadToken = m_Uploads.Register(file.FullName);

                    // The commands have been registered, so now load the dataset
                    Debug.Assert(
                        m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered.");
                    var applicationCommands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint);
                    var task = applicationCommands.Load(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        uploadToken);
                    task.Wait();

                    return(m_DatasetInformationBuilder(
                               planToImplement.DistributionFor.Id,
                               endpoint,
                               planToImplement.MachineToDistributeTo));
                }
                finally
                {
                    notifications.OnProgress -= progressHandler;
                }
            };

            return(Task <DatasetOnlineInformation> .Factory.StartNew(
                       result,
                       token,
                       TaskCreationOptions.LongRunning,
                       m_Scheduler));
        }
Exemple #4
0
        /// <summary>
        /// Takes the set of distribution plans and loads the given datasets onto the specified machines.
        /// </summary>
        /// <param name="planToImplement">The distribution plan that should be implemented.</param>
        /// <param name="token">The token used to indicate cancellation of the task.</param>
        /// <param name="progressReporter">The action that handles the reporting of progress.</param>
        /// <returns>
        /// A set of objects which allow act as proxies for the loaded datasets.
        /// </returns>
        public Task <DatasetOnlineInformation> ImplementPlan(
            DistributionPlan planToImplement,
            CancellationToken token,
            Action <int, string, bool> progressReporter)
        {
            Func <DatasetOnlineInformation> result =
                () =>
            {
                m_Diagnostics.Log(LevelToLog.Info, BaseConstants.LogPrefix, "Activating dataset");

                var        info = m_CommunicationLayer.LocalConnectionFor(ChannelType.NamedPipe);
                EndpointId endpoint;
                try
                {
                    endpoint = m_Loader.ActivateDataset(info.Item1, ChannelType.NamedPipe, info.Item2);
                }
                catch (Exception e)
                {
                    m_Diagnostics.Log(
                        LevelToLog.Error,
                        BaseConstants.LogPrefix,
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Failed to activate the dataset. Error was: {0}",
                            e));
                    throw;
                }

                var resetEvent = new AutoResetEvent(false);
                var commandAvailabilityNotifier =
                    Observable.FromEventPattern <CommandSetAvailabilityEventArgs>(
                        h => m_CommandHub.OnEndpointSignedIn += h,
                        h => m_CommandHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1);

                var notificationAvailabilityNotifier =
                    Observable.FromEventPattern <NotificationSetAvailabilityEventArgs>(
                        h => m_NotificationHub.OnEndpointSignedIn += h,
                        h => m_NotificationHub.OnEndpointSignedIn -= h)
                    .Where(args => args.EventArgs.Endpoint.Equals(endpoint))
                    .Take(1);

                var availability = commandAvailabilityNotifier.Zip(
                    notificationAvailabilityNotifier,
                    (a, b) => { return(true); })
                                   .Subscribe(
                    args =>
                {
                    resetEvent.Set();
                });

                using (availability)
                {
                    if (!m_CommandHub.HasCommandsFor(endpoint) || !m_NotificationHub.HasNotificationsFor(endpoint))
                    {
                        m_Diagnostics.Log(LevelToLog.Trace, BaseConstants.LogPrefix, "Waiting for dataset to connect.");

                        resetEvent.WaitOne();
                    }
                }

                m_Diagnostics.Log(LevelToLog.Trace, "Received commands and notifications from dataset.");

                IDatasetApplicationNotifications notifications;
                try
                {
                    notifications = m_NotificationHub.NotificationsFor <IDatasetApplicationNotifications>(endpoint);
                }
                catch (Exception e)
                {
                    m_Diagnostics.Log(
                        LevelToLog.Error,
                        BaseConstants.LogPrefix,
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Failed to get the notifications. Error was: {0}",
                            e));
                    throw;
                }

                EventHandler <ProgressEventArgs> progressHandler =
                    (s, e) => progressReporter(e.Progress, e.Description, e.HasErrors);
                notifications.OnProgress += progressHandler;
                try
                {
                    // Store the file
                    var file        = planToImplement.DistributionFor.StoredAt.AsFile();
                    var uploadToken = m_Uploads.Register(file.FullName);

                    // The commands have been registered, so now load the dataset
                    Debug.Assert(
                        m_CommandHub.HasCommandFor(endpoint, typeof(IDatasetApplicationCommands)), "No application commands registered.");
                    var commands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(endpoint);
                    var task     = commands.Load(
                        EndpointIdExtensions.CreateEndpointIdForCurrentProcess(),
                        uploadToken);
                    task.Wait();

                    // Now the dataset loading is complete
                    return(m_DatasetInformationBuilder(
                               planToImplement.DistributionFor.Id,
                               endpoint,
                               planToImplement.MachineToDistributeTo));
                }
                finally
                {
                    notifications.OnProgress -= progressHandler;
                }
            };

            return(Task <DatasetOnlineInformation> .Factory.StartNew(
                       result,
                       token,
                       TaskCreationOptions.LongRunning,
                       m_Scheduler));
        }