Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usability of SiloHostBuilder #3680

Closed
SebastianStehle opened this issue Nov 17, 2017 · 4 comments
Closed

Usability of SiloHostBuilder #3680

SebastianStehle opened this issue Nov 17, 2017 · 4 comments
Assignees
Milestone

Comments

@SebastianStehle
Copy link
Contributor

SebastianStehle commented Nov 17, 2017

Hi,

We are about to finalize the MongoDB provider for Orleans 2.0 (https://github.com/OrleansContrib/Orleans.Providers.MongoDB) and there is some confusing about the SiloHostBuilder and IProvider interface.

  1. What will happen with the XML configuration?
  2. How can I write extension methods for the SiloHostBuilder to register providers?
  3. What is the preferred Namespace for those extension methods? Just Orleans?
  4. Shall I support IProviderConfiguration or are options fine?

I think an method like the following would be good. It should run very last and must therefore implemented within the SiloHostBuilder

new SiloHostBuilder()
	.ConfigureCluster((cluster, configuration) => 
		cluster.Globals.RegisterStorageProvider<MongoDB>("Mongo", ...);
	})

I know that the final configuration model is in an state between the old and new system but it would be helpful to understand the plans.

@sergeybykov sergeybykov added this to the Triage milestone Nov 21, 2017
@jdom
Copy link
Member

jdom commented Nov 21, 2017

Hi, this is actually the biggest piece we are tackling for 2.0 since the beta was released. Right now the providers are in a very weird spot, but we plan to address them very soon.
The plan is that they will just rely on the strongly typed options (with the Microsoft.Extensions.Options infrastructure to configure them).
ClusterConfiguration and ClientConfiguration would hopefully just move to a legacy package and not be part of the core (we'll provide a way to transform the current legacy object into calls to configure the builder, similar to what we do here).
We recently merged some lifecycle functionality for starting/stopping Orleans services, which we'll expand to support providers, potentially removing the need for IProvider and that infrastructure entirely.
We are also adding a simplified way to use IOptions which will be particularly useful for named providers.
Also this issue can have a small impact on providers (last paragraph in the description)

We'll try to provide a simple migration path, but until it's fully done, it's a little hard to reason about what will be required for our 3rd party providers. I'd recommend you follow the upcoming PRs, because as I mentioned, these are the biggest features that remain for 2.0. I hope that even if not final, this response can help understand the short-term roadmap.

@sergeybykov sergeybykov modified the milestones: Triage, 2.0.0 Nov 30, 2017
@sergeybykov sergeybykov assigned jason-bragg and unassigned jdom Jan 6, 2018
@jason-bragg
Copy link
Contributor

Hello SebastianStehle,
As @jdom indicated, this work is still in flux. We have an issue covering the provider refactor "Provider model refactor #3737" and the first pass of this refactor is underway in PR "Remove provider management while maintaining support for legacy providers #3738".

We're committed to retaining support for the legacy providers (classes inheriting from IProvider). While there may be some minor breaking changes (hopefully not), for the most part we expect any providers that worked in 1.5.x to continue to work in 2.0. So the safest path available at this time is to code your provider to run against 1.5.x.

If, however, you want the provider to conform to the 2.0 preferred patterns, you'll need to develop it against the dev branch after PR #3738 has been merged, as it has the necessary infrastructure to support the new patterns. We suspect that PR will go in sometime this week, and we'll start porting (likely later this week, early next week) our supported providers to the new pattern after it goes in. Hopefully, our ports will serve as a working example.

While this is still in flux, the pattern (so far) for future providers is for them to be registered as named services in the container, while also taking part in the silo lifecycle. The provider initialization and shutdown will be controlled by the silo lifecycle as specified by the provider configuration. This ‘should’ provide all of the benefits of the legacy provider model with more flexibility, and less overhead. Since we plan to port some, if not all, of our supported providers to this pattern prior to the 2.0 release, we’ll be dog-fooding this pattern prior to expecting others to work with it.

@sergeybykov sergeybykov modified the milestones: 2.0.0, 2.0.0-rc Feb 8, 2018
@jason-bragg
Copy link
Contributor

Hello SebastianStehle,
We've ported many of our storage providers to the new pattern. As described in my previous post, the preferred pattern for grain storage is to register the storage provider as a named service, configured via options (Microsoft.Extensions.Options), and, should it need asynchronous initialization, registered as a lifecycle participant.

As a reference pattern, please take a look at AzureTableGrainStorage.

    public static IServiceCollection AddAzureTableGrainStorage(this IServiceCollection services, string name,
        Action<OptionsBuilder<AzureTableStorageOptions>> configureOptions = null)
    {
        // Add named option which configures the named instance of the component.
        configureOptions?.Invoke(services.AddOptions<AzureTableStorageOptions>(name));
        // Optional - Add validator for the component configuration.
        services.AddTransient<IConfigurationValidator>(sp => new AzureTableGrainStorageOptionsValidator(sp.GetService<IOptionsSnapshot<AzureTableStorageOptions>>().Get(name), name));
        // Optional - Register the component configuration values to be logged at silo start.
        // NOTE: If configuration has secrets in it, efforts need be made to ensure they are redacted.  (See usages of Redact attribute.
        services.ConfigureNamedOptionForLogging<AzureTableStorageOptions>(name);
        // Try to setup mapping to default grains storage.
        services.TryAddSingleton<IGrainStorage>(sp => sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
        // Register grain storage as a named IGrainStorage service.
        return services.AddSingletonNamedService<IGrainStorage>(name, AzureTableGrainStorageFactory.Create)
        // Register grain storage as a named lifecycle participant part service, for asynchronous initialization at startup.
        // NOTE: One may also choose to initialize on use, and some components may have synchronous initialization.  In either case, taking part in silo lifecycle would be unnecessary.
                       .AddSingletonNamedService<ILifecycleParticipant<ISiloLifecycle>>(name, (s, n) => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredServiceByName<IGrainStorage>(n));
    }

@sergeybykov
Copy link
Contributor

This is done in 2.0.0-rc1.

@ghost ghost locked as resolved and limited conversation to collaborators Sep 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants