How to implement custom resource to run in-process code with support for WaitForCompletion dependencies? #10943
-
I implemented a custom resource to convert a kubernetes ConfigMap data to a dictionary on the resource class. The config map can be sourced either from a real cluster or from a local yaml manifest file. A WithReference extension can then apply the resource's "outputs" dictionary to the respective resource that is using the extension. Conceptually the resource is an execute-once piece of code that is either Failed or Finished rather than a Running resource, but it doesn't fit the paradigm of running an executable command either. I'm guessing that my dependency issues explained later are due to the resource not fitting one of the Container, Project or Executable bases and subsequently their lifecycle management. I initially implemented the provisioning of the resource using AppHost lifecycle's BeforeStartEvent which was fine until I added the FromFile capability. From file allows me to load the configmap from a local manifest file. The file is created by a separate executable resource, a powershell script that renders manifests from helm charts. So basically I need my custom "configmap" resource to wait for completion on the executable resource. Because I implemented provisioning on BeforeStartEvent, there is no waiting on dependencies, and so the configmap resource provisioning reports "file not found". So my question is, what events do I subscribe to and/or what abstractions do I implement to support this type of code execution? Note: I really don't want to create a project to encapsulate the code. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
For a little more context, here's some code: public static IResourceBuilder<ConfigMapResource> AddConfigMap(this IDistributedApplicationBuilder builder,
string name,
string? @namespace = null,
string? context = null)
{
var resourceName = $"configmap-{name}";
var resource = new ConfigMapResource(resourceName)
{
ConfigMapName = name,
Namespace = @namespace ?? "default",
Context = context ?? "Default"
};
var resourceBuilder = builder.AddResource(resource)
.ExcludeFromManifest()
.WithInitialState(new CustomResourceSnapshot
{
ResourceType = "ConfigMap",
CreationTimeStamp = DateTime.UtcNow,
State = KnownResourceStates.NotStarted,
Properties =
[
new (CustomResourceKnownProperties.Source, "Kubernetes ConfigMap")
]
});
// If I subscribe to InitializeResourceEvent then provisioning happens but no waiting occurs.
// builder.Eventing.Subscribe<InitializeResourceEvent>(resource, ProvisionResource);
// If I subscribe to BeforeResourceStartedEvent then waiting occurs.....forever
// builder.Eventing.Subscribe<BeforeResourceStartedEvent>(resource, ProvisionResource);
return resourceBuilder;
} |
Beta Was this translation helpful? Give feedback.
-
We've updated https://github.com/dotnet/aspire/blob/main/docs/specs/appmodel.md to be a more complete guide for building resources. To enable your custom resource to be waited on you need to implement a lifecycle. You are not subscribing to events; you are publishing events (https://learn.microsoft.com/en-us/dotnet/aspire/app-host/eventing#resource-eventing) https://github.com/dotnet/aspire/blob/main/docs/specs/appmodel.md#example-custom-resource---talking-clock (ps there's no lifecycle hook anymore, just events). |
Beta Was this translation helpful? Give feedback.
We've updated https://github.com/dotnet/aspire/blob/main/docs/specs/appmodel.md to be a more complete guide for building resources.
To enable your custom resource to be waited on you need to implement a lifecycle. You are not subscribing to events; you are publishing events (https://learn.microsoft.com/en-us/dotnet/aspire/app-host/eventing#resource-eventing)
https://github.com/dotnet/aspire/blob/main/docs/specs/appmodel.md#example-custom-resource---talking-clock (ps there's no lifecycle hook anymore, just events).