[Bro-Dev] Broker::publish API

2018-07-27 Thread Robin Sommer
The other day when merging Johanna's code to clusterize the
configuration framework, I noticed this code in there:

 # [Send id=val to everyone else]

 Broker::publish(change_topic, Config::cluster_set_option, ID, val, 
location);

 if ( Cluster::local_node_type() != Cluster::MANAGER )
 Broker::relay(change_topic, change_topic, Config::cluster_set_option, 
ID, val, location);

It took me a bit to understand that ... The goal here is that a change
in a configuration value gets propagated out to all nodes in the
cluster. The Broker::publish() sends it to a node's immediate
neighbors, but not further. That means that for workers it goes (only)
to their manager; for the manager it means, it goes to all workers. If
we're not a manager, we then separately (through Broker::relay()) ask
our neighbors (that's the manager) to forward the change to *their*
neighbors (that's the other workers), without reraising it locally.

I remember we have discussed this API before, but I wanted to bring it
up again as I keep finding it confusing. I believe the code above
could be simplified by using the newer Broker::publish_and_relay(),
which was added to combine the two operations. Still, I'm realizing
now that I don't like thinking about this in terms of separate
publishing and relaying operations.

It all won't become easier once we add multi-hop routing to the mix
(which is in the works). And on top of all that, we also have
Cluster::publish_rr, Cluster::publish_hew, Cluster::relay_rr, and
Cluster::relay_hew -- another set of separate publishing & relay
options.

I'm wondering if we should give it another try to simply this API
while we still can (i.e., before 2.6 goes out). To me, the most
intuitive publish operation is "send to topic T and propagate to
everybody subscribed to that topic". I'd structure the API around
that, making that the main publish function for that simply:

Broker::publish(topic, args);

That would send to all neighbors, which then process locally and relay
to their neighbors. Right now, that would propagate just across one
hop but once we have multihop that'd start being broadcasted out
broadly.

To support the other use cases, we can then add modifiers & functions
to tweak this default, e.g.:

- Give publish() another argument "relay: bool &default=T" to prevent
  it from going beyond the immediate receiver. Or maybe instead:
  "relay_hops: int &default=-1" to specify the max number of hops
  to relay across, with -1 meaning no limit. (I recall concerns
  about loops being too easy to create; we could set the default
  here to F/0 to default to no forwarding, although conceptually I
  don't really like that :-)

- Give publish() another argument "relay_topic: string &default=""
  to change the topic when relaying on the 1st hop.

- Give publish() another argument "process_on_relays: bool &default=T"
  to change whether a relaying hop also sees the event locally.

- Add a second function publish_pool() that has all the same
  options, but receives a pool type instead of a topic (just an
  enum: RR, HRW).

What I'm not quite sure about is if some of these modifiers are better
to leave for the receiver to specify (e.g., whether to raise events
received on a given topic locally, or just forward). I think I can see
that either way.

Robin

-- 
Robin Sommer * Corelight, Inc. * ro...@corelight.com * www.corelight.com
___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev


Re: [Bro-Dev] Broker::publish API

2018-07-27 Thread Jon Siwek
On Fri, Jul 27, 2018 at 12:40 PM Robin Sommer  wrote:

> I'm wondering if we should give it another try to simply this API
> while we still can (i.e., before 2.6 goes out). To me, the most
> intuitive publish operation is "send to topic T and propagate to
> everybody subscribed to that topic". I'd structure the API around
> that, making that the main publish function for that simply:
>
> Broker::publish(topic, args);
>
> That would send to all neighbors, which then process locally and relay
> to their neighbors. Right now, that would propagate just across one
> hop but once we have multihop that'd start being broadcasted out
> broadly.

Can you remind/clarify what's meant by "multihop" ?  I thought:

Broker already has manual multihop if you set up subscriptions on all
relevant nodes on the path yourself.  Bro doesn't use it right now.

Broker does not yet have automatic multihop where subscriptions are
globally flooded automatically.

A difference between "manual multihop" and "automatic multihop" would
be that in the later, some relaying nodes may not actually hold a
subscription to the message they are relaying and so, in the case of
Bro events, I think they would not process them locally.

> - Give publish() another argument "relay: bool &default=T" to prevent
>   it from going beyond the immediate receiver. Or maybe instead:
>   "relay_hops: int &default=-1" to specify the max number of hops
>   to relay across, with -1 meaning no limit.

Going with the generalized approach of configurable number of hops per
message via "relay_hops" from the start would be better than finding
out we need it later.

Possibly a downside is now you need to store original hop limit in
addition to current TTL in each message if you want to detect the "is
1st hop" condition for the "relay_topic" option below.

> . (I recall concerns
>   about loops being too easy to create; we could set the default
>   here to F/0 to default to no forwarding, although conceptually I
>   don't really like that :-)

It's maybe both a concern and a reality -- Bro clusters currently
contain cycles (e.g. worker -> manager -> proxy -> worker)

> - Give publish() another argument "relay_topic: string &default=""
>   to change the topic when relaying on the 1st hop.
>
> - Give publish() another argument "process_on_relays: bool &default=T"
>   to change whether a relaying hop also sees the event locally.

Those seem fine to me.

> - Add a second function publish_pool() that has all the same
>   options, but receives a pool type instead of a topic (just an
>   enum: RR, HRW).

What's the goal of the enums instead of just publish_hrw() and publish_rr() ?

Instead of the API being 2 functions, it then seems like 2 enums that
are never used elsewhere + 1 function that now always branches
internally.

- Jon
___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev


Re: [Bro-Dev] Broker::publish API

2018-07-27 Thread Azoff, Justin S

> On Jul 27, 2018, at 1:39 PM, Robin Sommer  wrote:
> 
> I'm wondering if we should give it another try to simply this API
> while we still can (i.e., before 2.6 goes out). To me, the most
> intuitive publish operation is "send to topic T and propagate to
> everybody subscribed to that topic". I'd structure the API around
> that, making that the main publish function for that simply:
> 
>Broker::publish(topic, args);
> 
> That would send to all neighbors, which then process locally and relay
> to their neighbors. Right now, that would propagate just across one
> hop but once we have multihop that'd start being broadcasted out
> broadly.

This would do weird things on workers, since they connect to both the manager 
and proxies.

Worker 1 would send to it's neighbors [manager, proxy1, proxy2] but then those 
3 nodes would
relay to all of the other workers.  The TTL would stop the propagation, but 
you'd still end up sending
3 copies of the same message to each worker.

I do agree that there's room for a lot of simplification, for example a worker 
broadcasting a message efficiently to all
other workers needs to do something like this from the docs:

Cluster::relay_rr(Cluster::proxy_pool, "example_key",
  Cluster::worker_topic, worker_to_workers,
  Cluster::node + " (via a proxy)");

But a lot of that could have defaults:

Most use cases would want to relay through the default proxy pool
Since round robin is in use, they key shouldn't matter.
The round robin part itself is really an implementation detail for proxy load 
balancing and maybe not something that
should be exposed in the API.  Now that I think of it I'm not sure why one 
would ever use relay_hrw over relay_rr.

Removing a lot of that gets close to what you are suggesting:

Cluster::relay(Cluster::worker_topic, worker_to_workers, Cluster::node + " 
(via a proxy)");

which is I guess just

Cluster::relay(topic, args)

like you said.

— 
Justin Azoff


___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev


Re: [Bro-Dev] Broker::publish API

2018-07-27 Thread Jon Siwek
On Fri, Jul 27, 2018 at 3:55 PM Azoff, Justin S  wrote:

> I do agree that there's room for a lot of simplification, for example a 
> worker broadcasting a message efficiently to all
> other workers needs to do something like this from the docs:
>
> Cluster::relay_rr(Cluster::proxy_pool, "example_key",
>   Cluster::worker_topic, worker_to_workers,
>   Cluster::node + " (via a proxy)");
>
> But a lot of that could have defaults:
>
> Most use cases would want to relay through the default proxy pool
> Since round robin is in use, they key shouldn't matter.

At the moment, one could write their own wrapper function around that
if they find it too verbose and always want to use certain defaults?

> The round robin part itself is really an implementation detail for proxy load 
> balancing and maybe not something that
> should be exposed in the API.  Now that I think of it I'm not sure why one 
> would ever use relay_hrw over relay_rr.

Theoretically, a more favorable load distribution that's consistent
over time?  e.g. if you do RR of the same messaging pattern from
multiple nodes, you could have waves of "randomly" overlapping loads
on the relayer-node since everyone is cycling through all the proxies
at their own rate when choosing the relayer.  With HRW, you'd stick
with the same relayer over time and only change on outages, but
everyone should have chosen their relayer in a uniformly distributed
fashion.

- Jon
___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev


Re: [Bro-Dev] Broker::publish API

2018-07-27 Thread Azoff, Justin S

> On Jul 27, 2018, at 6:10 PM, Jon Siwek  wrote:
> 
> On Fri, Jul 27, 2018 at 3:55 PM Azoff, Justin S  wrote:
> 
>> I do agree that there's room for a lot of simplification, for example a 
>> worker broadcasting a message efficiently to all
>> other workers needs to do something like this from the docs:
>> 
>>Cluster::relay_rr(Cluster::proxy_pool, "example_key",
>>  Cluster::worker_topic, worker_to_workers,
>>  Cluster::node + " (via a proxy)");
>> 
>> But a lot of that could have defaults:
>> 
>> Most use cases would want to relay through the default proxy pool
>> Since round robin is in use, they key shouldn't matter.
> 
> At the moment, one could write their own wrapper function around that
> if they find it too verbose and always want to use certain defaults?

Yeah.. The wrapper would be trivial.. Should bro include it so that the API 
scripts use is simpler?


>> The round robin part itself is really an implementation detail for proxy 
>> load balancing and maybe not something that
>> should be exposed in the API.  Now that I think of it I'm not sure why one 
>> would ever use relay_hrw over relay_rr.
> 
> Theoretically, a more favorable load distribution that's consistent
> over time?  e.g. if you do RR of the same messaging pattern from
> multiple nodes, you could have waves of "randomly" overlapping loads
> on the relayer-node since everyone is cycling through all the proxies
> at their own rate when choosing the relayer.  With HRW, you'd stick
> with the same relayer over time and only change on outages, but
> everyone should have chosen their relayer in a uniformly distributed
> fashion.
> 
> - Jon

I'd expect that round robin would give the most uniform load distribution, for 
N proxies each proxy
would see 1/N relay messages, but I guess in general round robin isn't the best 
load balance mechanism
since it doesn't take into account the responsiveness of each proxy.  With some 
of the information CAF provides it
may be possible to also support weighted round robin.  That way if a proxy node 
doesn't die outright but starts
having issues for one reason or another, relay_rr could avoid sending it 
messages.

— 
Justin Azoff


___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev