Skip to content

Reexamine the data source API for multiple hosts #4578

@roji

Description

@roji

#4321 introduced DbDataSource support for Npgsql's multiple host feature. The same NpgsqlDataSourceBuilder is used to configure things, and then BuildMultiHost() is called instead of Build(), returning an NpgsqlMultiHostDataSource.

NpgsqlMultiHostDataSource extends NpgsqlDataSource, so you can get a connection from it as usual (that's equivalent to TargetSessionAttributes=Any). However, you can also do For(TargetSessionAttributes), getting a wrapping NpgsqlDataSource for a specific TargetSessionAttributes value.

Problems:

  • If the user changes their connection string from one host to multiple (or vice versa), they also need to change their code - this is not good. The same program should be able to work fine regardless of how many hosts are defined in the connection string (which is external config).
    • Of course, a program needs to be changed to specify specific values of TargetSessionAttributes. But I should be able to take an existing program that's unaware of multiple hosts, add multiple hosts to the connection string, and get transparent load balancing without any code changes.
    • Conversely, if my program uses multihost APIs (BuildMultiHost, For), it should ideally continue working even if I (temporarily?) change my connection string from multiple to one host. This would mean having a multi-host data source with just one host.
  • Needing to call BuildMultiHost() instead of Build() isn't great.
    • In theory, we could just have the multi-host APIs on the regular NpgsqlDataSource. But that may be burden for users who don't know/care about it (Intellisense etc.). It may be better to keep two NpgsqlDataSource types, so that only programs which opt into multiple hosts actually see it.
    • We could still decide to make the distinction earlier, e.g. have NpgsqlMultiHostDataSourceBuilder, whose Build() returns an NpgsqlMultiHostDataSource. Not sure there's much value in that over the current system though.
  • The For() naming isn't amazing, though I don't have anything substantially better. Wrap, WrapFor? With is pretty standard, but usually creates a modified copy of the thing (à la C# records), so doesn't seem appropriate.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions