2017-02-22 36 views
0

Возможно ли передать идентификатор экземпляра службы (значение int) в исполняемый файл guest во время выполнения? Я посмотрел на <ExeHost><Arguments>, но это полезно только для статических данных, которые должны быть предоставлены спереди.Передача идентификатора экземпляра службы в гостевой исполняемый файл во время выполнения

+0

Для чего вы собираетесь использовать? Он доступен (см. Мой ответ), но действительно ли это полезно, зависит от того, что вы планируете с ним делать. –

ответ

1

Он доступен в переменной окружения. Смотрите здесь для получения полного списка переменных окружения, доступных услуги: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-manage-multiple-environment-app-configuration

Обратите внимание, что один вы просите, Fabric_ServicePackageInstanceId, как правило, предназначена только для внутреннего потребления, и он идентифицирует весь пакет услуг. Это означает, что если у вас есть несколько пакетов кода (исполняемых файлов) в вашем пакете услуг, все они получат одинаковый идентификатор.

2

Переменная окружения предоставляет код экземпляра служебного пакета , который не совпадает с идентификатором экземпляра/реплики. Вообще говоря, переменные среды SF могут предоставлять одну и ту же информацию, используя FabricRuntime, то есть контекст узла и контекст активации пакета кода. В собственных службах SF идентификатор экземпляра предоставляется во время выполнения Fabric (в классе ServiceContext), поскольку один процесс может содержать несколько разделов и экземпляров/реплик.

В гостевом исполняемом файле, который не использует SF API, единственным вариантом AFAIK является запрос Fabric для этой информации в отдельный исполняемый файл, запуск его как SetupEntryPoint (который запускается каждый раз перед гостевым исполняемым файлом) и записывается информацию в файл.

Например (компилировать код в GetFabricData.exe и добавить его в пакет код):

private static async Task MainAsync(string[] args) 
{ 
    var serviceTypeName = args.FirstOrDefault(); 
    if (string.IsNullOrEmpty(serviceTypeName)) throw new ArgumentNullException(nameof(serviceTypeName)); 

    using (var client = new FabricClient()) 
    { 
     var activationContext = FabricRuntime.GetActivationContext(); 
     var nodeContext = FabricRuntime.GetNodeContext(); 
     var nodeName = nodeContext.NodeName; 
     var applicationName = new Uri(activationContext.ApplicationName); 

     var replicas = await client.QueryManager.GetDeployedReplicaListAsync(nodeName, applicationName); 
     // usually taking the first may not be correct 
     // but in a guest executable it's unlikely there would be multiple partitions/instances 
     var instance = replicas.OfType<DeployedStatelessServiceInstance>() 
      .FirstOrDefault(c => c.ServiceTypeName == serviceTypeName); 

     if (instance == null) 
     { 
      throw new InvalidOperationException($"Unable to find a service instance for {serviceTypeName}"); 
     } 

     File.WriteAllText("FabricData", instance.InstanceId.ToString()); 
    } 
} 

И в сервис манифеста:

<SetupEntryPoint> 
    <ExeHost> 
    <Program>GetFabricData.exe</Program> 
    <Arguments>Guest1Type</Arguments> 
    </ExeHost> 
</SetupEntryPoint> 

Затем гость исполняемый файл может просто читать FabricData файл.

+0

в моем случае гостевой исполняемый файл не соответствует SF, поэтому запрос не является вариантом. То, что сказал Вацлав, работает лучше всего. –

+0

@SeanFeldman Я так понимаю, я не предлагал добавить код SF в ваш исполняемый файл, но в другой exe, который будет запускаться в 'SetupEntryPoint'. SF запускает эту точку входа * перед * запуском гостевой exe, которая создаст файл с требуемыми данными. Такой подход позволит вам запрашивать информацию любого рода из Fabric без прямой зависимости от своих API. –

+0

это аккуратная идея. Сортировка загрузчика (или из задачи запуска «Облачные сервисы»). –