예제 #1
0
        private void AddNewEndpoint(EndpointId endpoint, IEnumerable <Type> commandTypes)
        {
            if (commandTypes.Contains(typeof(IDatasetActivationCommands)))
            {
                lock (m_Lock)
                {
                    if (!m_ActivatorCommands.ContainsKey(endpoint))
                    {
                        IDatasetActivationCommands command = null;
                        try
                        {
                            command = m_CommandHub.CommandsFor <IDatasetActivationCommands>(endpoint);
                        }
                        catch (CommandNotSupportedException)
                        {
                            // Secretly we actually don't have the command so just ignore this
                            // endpoint. This could be caused by the endpoint disappearing or
                            // some other networky problem.
                        }

                        if (command != null)
                        {
                            m_ActivatorCommands.Add(endpoint, command);
                        }
                    }
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Sends an echo message to the given endpoint.
 /// </summary>
 /// <param name="endpoint">The endpoint to which the message should be send.</param>
 /// <param name="messageText">The text of the message.</param>
 public void SendEchoMessageTo(EndpointId endpoint, string messageText)
 {
     if (m_Commands.HasCommandFor(endpoint, typeof(ITestCommandSet)))
     {
         var commands = m_Commands.CommandsFor <ITestCommandSet>(endpoint);
         commands.Echo(messageText, 10, 15 * 1000);
     }
 }
 /// <summary>
 /// Switches the dataset to edit mode.
 /// </summary>
 public void SwitchToEditMode()
 {
     if (!m_IsEditMode)
     {
         Debug.Assert(m_CommandHub.HasCommandFor(Endpoint, typeof(IDatasetApplicationCommands)), "Missing essential command set.");
         var commands = m_CommandHub.CommandsFor <IDatasetApplicationCommands>(Endpoint);
         var result   = commands.SwitchToEditMode();
         result.ContinueWith(
             t =>
         {
             if (t.Exception != null)
             {
                 m_Diagnostics.Log(
                     LevelToLog.Error,
                     BaseConstants.LogPrefix,
                     string.Format(
                         CultureInfo.InvariantCulture,
                         "The begin edit dataset task threw an exception. Exception details: {0}",
                         t.Exception));
             }
         });
     }
 }
        /// <summary>
        /// An event handler which is invoked when the search for an assembly fails.
        /// </summary>
        /// <param name="sender">The object which raised the event.</param>
        /// <param name="args">
        ///     The <see cref="System.ResolveEventArgs"/> instance containing the event data.
        /// </param>
        /// <returns>
        ///     An assembly reference if the required assembly can be found; otherwise <see langword="null"/>.
        /// </returns>
        public Assembly LocatePluginAssembly(object sender, ResolveEventArgs args)
        {
            var name = new AssemblyName(args.Name);

            var commands    = m_HostCommands.CommandsFor <IHostApplicationCommands>(m_HostId);
            var prepareTask = commands.PreparePluginContainerForTransfer(name);

            try
            {
                prepareTask.Wait();
            }
            catch (AggregateException)
            {
                return(null);
            }

            var file = m_FileSystem.Path.GetTempFileName();

            try
            {
                var finalAssemblyPath = string.Format(CultureInfo.InvariantCulture, "{0}.dll", name.Name);

                var streamTask = m_Layer(m_HostId, prepareTask.Result, file);
                var copyTask   = streamTask.ContinueWith(
                    t => m_FileSystem.File.Move(t.Result.FullName, finalAssemblyPath),
                    TaskContinuationOptions.ExecuteSynchronously);

                try
                {
                    copyTask.Wait();
                }
                catch (AggregateException)
                {
                    return(null);
                }

                // The assembly should be here now so we should be able to load it
                return(Assembly.Load(name));
            }
            finally
            {
                if (m_FileSystem.File.Exists(file))
                {
                    m_FileSystem.File.Delete(file);
                }
            }
        }
예제 #5
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));
        }