Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Nov 20, 2023. It is now read-only.
Prev Previous commit
Next Next commit
Spin up dapr placement container automatically
  • Loading branch information
dasiths committed Dec 2, 2020
commit aa56c46501be2243cc1926ca0e4b68d76e4fdbe9
77 changes: 56 additions & 21 deletions src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,61 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati

if (context.Operation == ExtensionContext.OperationKind.LocalRun)
{
// default placement port number
var placementPort = 50005;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a random port instead of a specific port?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will now use the next available port, same as the other parts of the system.

var isCustomPlacementPort = false;

var existingDaprPlacementDefinition = context.Application.Services.FirstOrDefault(s =>
s is ContainerServiceBuilder serviceBuilder && serviceBuilder.Image == "daprio/dapr");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of using ImageName + Tag, placement definition cannot be found.
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I think about this, the more I don't like sniffing to determine if the placement port is already defined or not.

I think including an option called excludePlacementService, which default to false, is enough to have people either include or exclude it as required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed sniffing. It will now use an auto assigned port and be agnostic about the user defined services. The only way to control the port is via the placement-port property.


// see if a placement port number has been defined at the extension level
if (config.Data.TryGetValue("placement-port", out var obj) && obj?.ToString() is string && int.TryParse(obj.ToString(), out var customPlacementPort))
{
context.Output.WriteDebugLine($"Using Dapr placement service port {customPlacementPort} from 'placement-port'");
placementPort = customPlacementPort;
isCustomPlacementPort = true;
}

// check to see if a custom service definition for the placement container exists.
if (existingDaprPlacementDefinition == null)
{
context.Output.WriteDebugLine("Dapr placement service not defined in Tye.yaml. Trying to create one...");

if (!(config.Data.TryGetValue("exclude-placement-container", out obj) &&
obj?.ToString() is string excludePlacementContainer && excludePlacementContainer == "true"))
{
context.Output.WriteDebugLine("Injecting Dapr placement service...");
var daprPlacement = new ContainerServiceBuilder("placement", "daprio/dapr")
{
Args = "./placement",
Bindings = {
new BindingBuilder() {
Port = placementPort,
ContainerPort = 50005,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the container port always supposted to be 50005 for the placement?

Copy link
Member Author

@dasiths dasiths Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's defined by Dapr. I did however introduce a new property called placement-container-port to allow the developer to set it if required. (i.e. If Dapr releases a new image with a new port). Similarly I now have a placement-image which allows the developers to define a custom image name if required. (i.e. daprio/dapr:edge)

Protocol = "http"
}
}
};
context.Application.Services.Add(daprPlacement);
}
else
{
context.Output.WriteDebugLine("Skipping injecting Dapr placement service because 'exclude-placement-container=true'...");
}
}
else
{
// use the port defined in the custom service definition is possible
var definedPlacementPort = existingDaprPlacementDefinition.Bindings.FirstOrDefault(b => b.Port.HasValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on my suggestion earlier, I think if someone sets excludePlacementService, they must define placement-port so we know what that is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I added this check now. It will ignore exclude-placement-service if not placement-port has been defined.

if (definedPlacementPort?.Port != null && !isCustomPlacementPort)
{
context.Output.WriteDebugLine($"Using Dapr placement service port {definedPlacementPort.Port.Value} from service definition...");
placementPort = definedPlacementPort.Port.Value;
}

context.Output.WriteDebugLine("Skipping injecting Dapr placement service because it's already defined in Tye.yaml...");
}

// For local run, enumerate all projects, and add services for each dapr proxy.
var projects = context.Application.Services.OfType<ProjectServiceBuilder>().ToList();
foreach (var project in projects)
Expand All @@ -45,35 +100,15 @@ public override Task ProcessAsync(ExtensionContext context, ExtensionConfigurati

var daprExecutablePath = GetDaprExecutablePath();


var proxy = new ExecutableServiceBuilder($"{project.Name}-dapr", daprExecutablePath)
{
WorkingDirectory = context.Application.Source.DirectoryName,

// These environment variables are replaced with environment variables
// defined for this service.
Args = $"-app-id {project.Name} -app-port %APP_PORT% -dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT%",
Args = $"-app-id {project.Name} -app-port %APP_PORT% -dapr-grpc-port %DAPR_GRPC_PORT% --dapr-http-port %DAPR_HTTP_PORT% --metrics-port %METRICS_PORT% --placement-address=localhost:{placementPort}",
};

if (config.Data.TryGetValue("placement-address", out var obj) && obj?.ToString() is string customPlacementAddressValue)
{
proxy.Args += $" --placement-address {customPlacementAddressValue}";
}
else
{
var placementAddress = "localhost:50005";

// Note: This port inferring logic was causing the tests to fail. Keeping it here for now but will remove based on PR feedback.

//if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
//{
// // Dapr running on WSL2 backend has placement container like 0.0.0.0:6050->50005/tcp
// placementAddress = "localhost:6050";
//}

proxy.Args += $" --placement-address {placementAddress}";
}

// When running locally `-config` specifies a filename, not a configuration name. By convention
// we'll assume the filename and config name are the same.
if (config.Data.TryGetValue("config", out obj) && obj?.ToString() is string daprConfig)
Expand Down