Skip to content

Conversation

@the-mikedavis
Copy link
Contributor

This can be used to efficiently query for specific counters across all ids in a group. Equivalently you could use counters/1 and then maps:fold/3, however this counters/1 creates a map of maps with all counters - this introduces a lot of intermediary garbage.

This can be used to efficiently query for specific counters across all
`id`s in a `group`. Equivalently you could use `counters/1` and then
`maps:fold/3`, however this `counters/1` creates a map of maps with
all counters - this introduces a lot of intermediary garbage.
Copy link
Contributor Author

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was imagining that this could be nice for rabbitmq/rabbitmq-server#15098. With rabbitmq/osiris#197 we could efficiently find all writers with replicas that are behind, something like:

seshat:fold(
  fun ({osiris_writer, SQ}, CRef, Acc) ->
          case counters:get(CRef, 9) > MaxDiff of
              true ->
                  [SQ | Acc];
              false ->
                  Acc
          end;
      (_, _, Acc) ->
          Acc
  end, [], osiris).

Comment on lines +204 to +207
fold(Fun, Acc0, Group) ->
ets:foldl(fun(#entry{id = Id, cref = CRef}, Acc) ->
Fun(Id, CRef, Acc)
end, Acc0, seshat_counters_server:get_table(Group)).
Copy link
Contributor Author

@the-mikedavis the-mikedavis Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API-wise, passing the counters ref feels wrong. Ideally we could take advantage of the #entry.field_spec here so that the fold function could use the field name atoms instead of indexes.

Maybe we can pass in a function? Something like:

fold(Fun, Acc0, Group) ->
    ets:foldl(fun(#entry{id = Id,
                         field_spec = FieldsSpec,
                         cref = CRef}, Acc) ->
                      Fields = resolve_fields_spec(FieldsSpec),
                      GetCounterFun = fun(Field) ->
                                          %% lists:keyfind/3 the field and use
                                          %% its index with counters:get/2
                                      end,
                      Fun(Id, GetCounterFun, Acc)
              end, Acc0, seshat_counters_server:get_table(Group)).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also - seems like it might be valuable to make fields_spec() a map keyed by name? I think that would benefit a few of the functions in this module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant