Возможно ли передать идентификатор экземпляра службы (значение int) в исполняемый файл guest во время выполнения? Я посмотрел на <ExeHost><Arguments>
, но это полезно только для статических данных, которые должны быть предоставлены спереди.Передача идентификатора экземпляра службы в гостевой исполняемый файл во время выполнения
ответ
Он доступен в переменной окружения. Смотрите здесь для получения полного списка переменных окружения, доступных услуги: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-manage-multiple-environment-app-configuration
Обратите внимание, что один вы просите, Fabric_ServicePackageInstanceId, как правило, предназначена только для внутреннего потребления, и он идентифицирует весь пакет услуг. Это означает, что если у вас есть несколько пакетов кода (исполняемых файлов) в вашем пакете услуг, все они получат одинаковый идентификатор.
Переменная окружения предоставляет код экземпляра служебного пакета , который не совпадает с идентификатором экземпляра/реплики. Вообще говоря, переменные среды 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
файл.
в моем случае гостевой исполняемый файл не соответствует SF, поэтому запрос не является вариантом. То, что сказал Вацлав, работает лучше всего. –
@SeanFeldman Я так понимаю, я не предлагал добавить код SF в ваш исполняемый файл, но в другой exe, который будет запускаться в 'SetupEntryPoint'. SF запускает эту точку входа * перед * запуском гостевой exe, которая создаст файл с требуемыми данными. Такой подход позволит вам запрашивать информацию любого рода из Fabric без прямой зависимости от своих API. –
это аккуратная идея. Сортировка загрузчика (или из задачи запуска «Облачные сервисы»). –
Для чего вы собираетесь использовать? Он доступен (см. Мой ответ), но действительно ли это полезно, зависит от того, что вы планируете с ним делать. –