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

Using Slice without Slice definitions #4011

Open
bernardnormier opened this issue Jul 1, 2024 · 2 comments
Open

Using Slice without Slice definitions #4011

bernardnormier opened this issue Jul 1, 2024 · 2 comments
Labels
enhancement proposal Proposal for a new feature or significant update
Milestone

Comments

@bernardnormier
Copy link
Member

The current process when writing an IceRPC+Slice application is:
a) describe your Slice interfaces in a Slice file (.slice)
b) generate code from these Slice files with the Slice compiler
c) write your own code that calls the generated proxy (for invocations) or implements the generated Service interfaces (for service implementations)

This is a proposal to allow IceRPC users to skip (a) and (b), and write IceRPC+Slice applications without Slice files or the Slice compiler.

Note that this proposed path is an alternative to the current path. Not a replacement.

Proxies

If you write a client application, you could define a Slice proxy by adding an attribute to your own hand-written interface, for example:

namespace Xyz;

[SliceProxy] 
interface IGreeter
{
    Task<string> GreetAsync(string name, CancellationToken cancellationToken = default);
}

[IceRpc.Slice.SliceProxy] instructs the IceRpc+Slice source generator to generate a NameProxy struct that implements all the methods of this interface. These methods must return a Task or Task<T> and have an Async suffix. The features parameter is optional (i.e. the user doesn't need to include it). Maybe the cancellationToken can be optional too.

We would offer some level of customization for the generated proxy, such as the ability to set the default path and the ability to set the operation name (all via attributes).

Services

If you write a server application, you can define a service by adding an attribute to your hand-written class:

namespace Xyz.Server;

[SliceService] 
internal partial class Chatbot // must be partial
{
   // any access-level is fine
   internal ValueTask<string> GreetAsync(string name, CancellationToken cancellationToken)
   {
        Console.WriteLine($"Dispatching greet request {{ name = '{name}' }}");
        return new($"Hello, {name}!");
   }
}

The (existing) attribute [IceRpc.Slice.SliceService] instructs the IceRpc+Slice source generator to implement IDispatcher using the xxxAsync methods defined by this class.

Like for the proxy methods, IFeatureCollection and possibly CancellationToken would be optional. We would also provide an attribute to exclude methods from the source-generated dispatch.

Related issue: #3738.

@bernardnormier bernardnormier added proposal Proposal for a new feature or significant update enhancement labels Jul 1, 2024
@bernardnormier bernardnormier added this to the Future milestone Jul 1, 2024
@pepone
Copy link
Member

pepone commented Jul 1, 2024

How would you deal with Enum/struct parameters that rely on generated code for marshaling?

@bernardnormier
Copy link
Member Author

The parameters of implicitly defined Slice operations need to be encodable/decodable. So they are either primitive types like String and int, or they are user-defined types with Slice attributes.

For example:

[SliceType] // source generator provides encoding/decoding support
struct MyStruct {
   ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement proposal Proposal for a new feature or significant update
Projects
None yet
Development

No branches or pull requests

2 participants