Due to technicalities parts of the original code were licensed under
BSL.
In preparations for the public release of the feature, the license has
been changed to Apache 2.0
Attempt to mitigate this frequent source of flakiness:
```
=CRASH REPORT==== 31-Jan-2024::17:30:15.025404 ===
crasher:
initial call: emqx_ds_replication_layer_egress:init/1
pid: <0.11312.0>
registered_name: []
exception error: no match of right hand side value {error,
no_leader_for_shard}
in function emqx_ds_replication_layer_egress:init/1 (/emqx/apps/emqx_durable_storage/src/emqx_ds_replication_layer_egress.erl, line 93)
in call from gen_server:init_it/2 (gen_server.erl, line 980)
in call from gen_server:init_it/6 (gen_server.erl, line 935)
ancestors: [<0.11310.0>,<0.11304.0>,emqx_ds_builtin_databases_sup,
emqx_ds_builtin_sup,emqx_ds_sup,<0.11236.0>]
message_queue_len: 0
messages: []
links: [<0.11310.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 376
stack_size: 28
reductions: 231
neighbours:
```
Part of https://emqx.atlassian.net/browse/EMQX-10942
The goal is to help make it clear to the caller of `next` what to do next: if the iterator
should still be used or if no new messages will ever come out of it.
From:
```erlang
-spec next(iterator()) -> {value, binary(), iterator()} | none | {error, closed}.
```
To:
```erlang
-spec next(iterator()) -> {ok, iterator(), [binary()]} | end_of_stream.
-spec next(iterator(), pos_integer()) -> {ok, iterator(), [binary()]} | end_of_stream.
```
Fixes https://emqx.atlassian.net/browse/EMQX-10579
This introduces the concept of "keyspaces" to our durable storage (DS) implementation, and
also refactors some places where "shard" and "keyspace" would be mixed up.
We might want to tune the storage options differently for distinct sets of topics, the
keyspaces. The keyspace is composed by one or more shards.
- Keyspaces are identified simply by binary strings.
- DS configuration is scoped by keyspaces instead of shards.
- Starting a new DS shard requires definining to which keyspace the shard belongs.