|
Posted
about 10 years
ago
We gladly announce the second pre-release of CAF version 0.15. A big thank you
goes to our early adopters! You helped us to improve CAF with reports on bugs
and API flaws on the mailing list as well as on GitHub. Needless to say, this
release
... [More]
contains many bug fixes as a result. Further, our new
type inspection
API is now in place. You can also
spawn actors remotely
using our new experimental API.
CAF now enters the feature freeze phase and we are confident to ship 0.15 end
of August.
[Less]
|
|
Posted
about 10 years
ago
The first pre-release version of 0.15 has just been released! As outlined in
our previous post,
this version comes with breaking changes. However, we think the end result is
well worth it. This release is the result of 8 months of development and 374
... [More]
commits.
The best starting points to learn the new API is to read the
examples
and the extensively updated manual (as
HTML or
PDF).
Special thanks go to our early adopters for feedback, discussion, and bug
fixing!
Our goal with this pre-release is to stabilize the API. We have one planned
feature for the next pre-release that allows users to write
less boilerplate
code for serialization and string conversion. However, this change will be
backwards compatible. Please do not hesitate to propose changes to the current
API on GitHub.
By the way, configuring your CAF application is now incredibly easy. We support
CLI options as well as separate INI files. The new manual has an entire
section
dedicated to the new extensible config mechanism.
We plan to release the next pre-release end of July. Whether or not we release
a third pre-release version depends on the amount of user feedback we get (and
how many bugs we find). If all goes well, we will ship 0.15 in August. [Less]
|
|
Posted
about 10 years
ago
The first pre-release version of 0.15 has just been released! As outlined in
our previous post,
this version comes with breaking changes. However, we think the end result is
well worth it. This release is the result of 8 months of development and 374
... [More]
commits.
The best starting points to learn the new API is to read the
examples
and the extensively updated manual (as
HTML or
PDF).
Special thanks go to our early adopters for feedback, discussion, and bug
fixing!
Our goal with this pre-release is to stabilize the API. We have one planned
feature for the next pre-release that allows users to write
less boilerplate
code for serialization and string conversion. However, this change will be
backwards compatible. Please do not hesitate to propose changes to the current
API on GitHub.
By the way, configuring your CAF application is now incredibly easy. We support
CLI options as well as separate INI files. The new manual has an entire
section
dedicated to the new extensible config mechanism.
We plan to release the next pre-release end of July. Whether or not we release
a third pre-release version depends on the amount of user feedback we get (and
how many bugs we find). If all goes well, we will ship 0.15 in August.
[Less]
|
|
Posted
over 10 years
ago
Sometimes, a design outlives its usefulness. CAF started with its first commit
on March 4, 2011. Its mission statement? Provide a lightweight, domain-specifc
language (DSL) for actors in C++. The user-facing API should be as minimalistic
as possible
... [More]
by hiding internal state of the actor runtime. Key components, such
as scheduler or middleman, run as lazily initialized singletons. This design
works great as long as applications do not wish to configure parameters of
these global components. With a growing user base and more fields of
applications, it becomes clear that hiding as much state of the system as
possible puts obstacles in the way of many users.
After much consideration, we decided to start over with a API in 0.15.
The next release of CAF embodies our vision for a 1.0 release, and
addresses the vibrant feedback we received over the years. The new anchor of
CAF applications is actor_system, which replaces the previous singleton-based
design. An actor system encapsulates runtime state, which CAF previously
maintained globally, such as announced type information and scheduler behavior.
Users can now fully control the initialization phase of an actor system.
Aside from improved configurability, this change has the advantage that
multiple actor systems can now co-exist in the same process, e.g., one with a
scheduler tuned for high-throughput and one with a scheduler optimized for low
latency scenarios.
With CAF 0.15, we replaced misleading function names with more intuitive ones
(e.g., sync_send with request). We also improved the reference counting
implementation used for actor garbage collection. Without further ado, this is
how the Hello World example will look in 0.15:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->request(buddy, std::chrono::seconds(10), "Hello World!").then(
// ... wait up to 10s for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// our CAF environment
actor_system system;
// create a new actor that calls 'mirror()'
auto mirror_actor = system.spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
system.spawn(hello_world, mirror_actor);
// system will wait until both actors are destroyed before leaving main
}
For comparison, this is the same code in 0.14:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// terminates this actor ('become' otherwise loops forever)
self->quit();
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->sync_send(buddy, "Hello World!").then(
// ... wait for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// create a new actor that calls 'mirror()'
auto mirror_actor = spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
spawn(hello_world, mirror_actor);
// wait until all other actors we have spawned are done
await_all_actors_done();
// run cleanup code before exiting main
shutdown();
}
Most notably, we no longer need to call await_all_actors_done() and
shutdown() in main(). Nor does the mirror actor need to call quit()
explicitly. Once system goes out of scope, it will wait (i.e., block) for all
remaining actors before cleaning up. The mirror actor is destroyed implicitly
once there is no more reference to it. Finally, sync_send has been renamed to
request and now requires a timeout.
Additionally, dynamically and statically typed actors now exhibit a symmetric
API. We also provide new ways to compose actors and the behavior of actors. If
you are interested in the current state of development, check out the
topic/actor-system branch. It is in development since November 2015,
currently contains 200 commits, and will get merged into develop soon.
Since version 0.15 has many API changes, we will release at least one
pre-release version for collecting user feedback and finalizing the API. The
first pre-release is scheduled for June and will include a complete overhaul of
the user manual. It was not an easy decision to break the API on so many
layers. However, the changes are the result of all the feedback we received
over years as well as our own experiences with using CAF on a daily basis.
This makes version 0.15 the most important milestone towards a stable 1.0
release.
[Less]
|
|
Posted
over 10 years
ago
Sometimes, a design outlives its usefulness. CAF started with its first commit
on March 4, 2011. Its mission statement? Provide a lightweight, domain-specifc
language (DSL) for actors in C++. The user-facing API should be as minimalistic
as possible
... [More]
by hiding internal state of the actor runtime. Key components, such
as scheduler or middleman, run as lazily initialized singletons. This design
works great as long as applications do not wish to configure parameters of
these global components. With a growing user base and more fields of
applications, it becomes clear that hiding as much state of the system as
possible puts obstacles in the way of many users.
After much consideration, we decided to start over with a API in 0.15.
The next release of CAF embodies our vision for a 1.0 release, and
addresses the vibrant feedback we received over the years. The new anchor of
CAF applications is actor_system, which replaces the previous singleton-based
design. An actor system encapsulates runtime state, which CAF previously
maintained globally, such as announced type information and scheduler behavior.
Users can now fully control the initialization phase of an actor system.
Aside from improved configurability, this change has the advantage that
multiple actor systems can now co-exist in the same process, e.g., one with a
scheduler tuned for high-throughput and one with a scheduler optimized for low
latency scenarios.
With CAF 0.15, we replaced misleading function names with more intuitive ones
(e.g., sync_send with request). We also improved the reference counting
implementation used for actor garbage collection. Without further ado, this is
how the Hello World example will look in 0.15:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->request(buddy, std::chrono::seconds(10), "Hello World!").then(
// ... wait up to 10s for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// our CAF environment
actor_system system;
// create a new actor that calls 'mirror()'
auto mirror_actor = system.spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
system.spawn(hello_world, mirror_actor);
// system will wait until both actors are destroyed before leaving main
}
For comparison, this is the same code in 0.14:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// terminates this actor ('become' otherwise loops forever)
self->quit();
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->sync_send(buddy, "Hello World!").then(
// ... wait for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// create a new actor that calls 'mirror()'
auto mirror_actor = spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
spawn(hello_world, mirror_actor);
// wait until all other actors we have spawned are done
await_all_actors_done();
// run cleanup code before exiting main
shutdown();
}
Most notably, we no longer need to call await_all_actors_done() and
shutdown() in main(). Nor does the mirror actor need to call quit()
explicitly. Once system goes out of scope, it will wait (i.e., block) for all
remaining actors before cleaning up. The mirror actor is destroyed implicitly
once there is no more reference to it. Finally, sync_send has been renamed to
request and now requires a timeout.
Additionally, dynamically and statically typed actors now exhibit a symmetric
API. We also provide new ways to compose actors and the behavior of actors. If
you are interested in the current state of development, check out the
topic/actor-system branch. It is in development since November 2015,
currently contains 200 commits, and will get merged into develop soon.
Since version 0.15 has many API changes, we will release at least one
pre-release version for collecting user feedback and finalizing the API. The
first pre-release is scheduled for June and will include a complete overhaul of
the user manual. It was not an easy decision to break the API on so many
layers. However, the changes are the result of all the feedback we received
over years as well as our own experiences with using CAF on a daily basis.
This makes version 0.15 the most important milestone towards a stable 1.0
release. [Less]
|
|
Posted
over 10 years
ago
Sometimes, a design outlives its usefulness. CAF started with its first commit
on March 4, 2011. Its mission statement? Provide a lightweight, domain-specifc
language (DSL) for actors in C++. The user-facing API should be as minimalistic
as possible
... [More]
by hiding internal state of the actor runtime. Key components, such
as scheduler or middleman, run as lazily initialized singletons. This design
works great as long as applications do not wish to configure parameters of
these global components. With a growing user base and more fields of
applications, it becomes clear that hiding as much state of the system as
possible puts obstacles in the way of many users.
After much consideration, we decided to start over with a API in 0.15.
The next release of CAF embodies our vision for a 1.0 release, and
addresses the vibrant feedback we received over the years. The new anchor of
CAF applications is actor_system, which replaces the previous singleton-based
design. An actor system encapsulates runtime state, which CAF previously
maintained globally, such as announced type information and scheduler behavior.
Users can now fully control the initialization phase of an actor system.
Aside from improved configurability, this change has the advantage that
multiple actor systems can now co-exist in the same process, e.g., one with a
scheduler tuned for high-throughput and one with a scheduler optimized for low
latency scenarios.
With CAF 0.15, we replaced misleading function names with more intuitive ones
(e.g., sync_send with request). We also improved the reference counting
implementation used for actor garbage collection. Without further ado, this is
how the Hello World example will look in 0.15:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->request(buddy, std::chrono::seconds(10), "Hello World!").then(
// ... wait up to 10s for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// our CAF environment
actor_system system;
// create a new actor that calls 'mirror()'
auto mirror_actor = system.spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
system.spawn(hello_world, mirror_actor);
// system will wait until both actors are destroyed before leaving main
}
For comparison, this is the same code in 0.14:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// terminates this actor ('become' otherwise loops forever)
self->quit();
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->sync_send(buddy, "Hello World!").then(
// ... wait for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// create a new actor that calls 'mirror()'
auto mirror_actor = spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
spawn(hello_world, mirror_actor);
// wait until all other actors we have spawned are done
await_all_actors_done();
// run cleanup code before exiting main
shutdown();
}
Most notably, we no longer need to call await_all_actors_done() and
shutdown() in main(). Nor does the mirror actor need to call quit()
explicitly. Once system goes out of scope, it will wait (i.e., block) for all
remaining actors before cleaning up. The mirror actor is destroyed implicitly
once there is no more reference to it. Finally, sync_send has been renamed to
request and now requires a timeout.
Additionally, dynamically and statically typed actors now exhibit a symmetric
API. We also provide new ways to compose actors and the behavior of actors. If
you are interested in the current state of development, check out the
topic/actor-system branch. It is in development since November 2015,
currently contains 200 commits, and will get merged into develop soon.
Since version 0.15 has many API changes, we will release at least one
pre-release version for collecting user feedback and finalizing the API. The
first pre-release is scheduled for June and will include a complete overhaul of
the user manual. It was not an easy decision to break the API on so many
layers. However, the changes are the result of all the feedback we received
over years as well as our own experiences with using CAF on a daily basis.
This makes version 0.15 the most important milestone towards a stable 1.0
release.
[Less]
|
|
Posted
over 10 years
ago
Sometimes, a design outlives its usefulness. CAF started with its first commit
on March 4, 2011. Its mission statement? Provide a lightweight, domain-specifc
language (DSL) for actors in C++. The user-facing API should be as minimalistic
as possible
... [More]
by hiding internal state of the actor runtime. Key components, such
as scheduler or middleman, run as lazily initialized singletons. This design
works great as long as applications do not wish to configure parameters of
these global components. With a growing user base and more fields of
applications, it becomes clear that hiding as much state of the system as
possible puts obstacles in the way of many users.
After much consideration, we decided to start over with a API in 0.15.
The next release of CAF embodies our vision for a 1.0 release, and
addresses the vibrant feedback we received over the years. The new anchor of
CAF applications is actor_system, which replaces the previous singleton-based
design. An actor system encapsulates runtime state, which CAF previously
maintained globally, such as announced type information and scheduler behavior.
Users can now fully control the initialization phase of an actor system.
Aside from improved configurability, this change has the advantage that
multiple actor systems can now co-exist in the same process, e.g., one with a
scheduler tuned for high-throughput and one with a scheduler optimized for low
latency scenarios.
With CAF 0.15, we replaced misleading function names with more intuitive ones
(e.g., sync_send with request). We also improved the reference counting
implementation used for actor garbage collection. Without further ado, this is
how the Hello World example will look in 0.15:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->request(buddy, std::chrono::seconds(10), "Hello World!").then(
// ... wait up to 10s for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// our CAF environment
actor_system system;
// create a new actor that calls 'mirror()'
auto mirror_actor = system.spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
system.spawn(hello_world, mirror_actor);
// system will wait until both actors are destroyed before leaving main
}
For comparison, this is the same code in 0.14:
behavior mirror(event_based_actor* self) {
// return the (initial) actor behavior
return {
// a handler for messages containing a single string
// that replies with a string
[=](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout(self) << what << endl;
// terminates this actor ('become' otherwise loops forever)
self->quit();
// reply "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
};
}
void hello_world(event_based_actor* self, const actor& buddy) {
// send "Hello World!" to our buddy ...
self->sync_send(buddy, "Hello World!").then(
// ... wait for a response ...
[=](const string& what) {
// ... and print it
aout(self) << what << endl;
}
);
}
int main() {
// create a new actor that calls 'mirror()'
auto mirror_actor = spawn(mirror);
// create another actor that calls 'hello_world(mirror_actor)';
spawn(hello_world, mirror_actor);
// wait until all other actors we have spawned are done
await_all_actors_done();
// run cleanup code before exiting main
shutdown();
}
Most notably, we no longer need to call await_all_actors_done() and
shutdown() in main(). Nor does the mirror actor need to call quit()
explicitly. Once system goes out of scope, it will wait (i.e., block) for all
remaining actors before cleaning up. The mirror actor is destroyed implicitly
once there is no more reference to it. Finally, sync_send has been renamed to
request and now requires a timeout.
Additionally, dynamically and statically typed actors now exhibit a symmetric
API. We also provide new ways to compose actors and the behavior of actors. If
you are interested in the current state of development, check out the
topic/actor-system branch. It is in development since November 2015,
currently contains 200 commits, and will get merged into develop soon.
Since version 0.15 has many API changes, we will release at least one
pre-release version for collecting user feedback and finalizing the API. The
first pre-release is scheduled for June and will include a complete overhaul of
the user manual. It was not an easy decision to break the API on so many
layers. However, the changes are the result of all the feedback we received
over years as well as our own experiences with using CAF on a daily basis.
This makes version 0.15 the most important milestone towards a stable 1.0
release.
[Less]
|
|
Posted
almost 11 years
ago
For our second article in the spotlight series, we want to higlight the popular
open source network monitor Bro and talk to the core
development team in Berkeley, California.
Background: Bro(ker)
Bro is an open source network analysis
... [More]
framework, well grounded in 15 years of
research. While focusing on network security monitoring, Bro provides a
comprehensive platform for more general network traffic analysis as well. Bro's
user community includes major universities, research labs, supercomputing
centers, open-science communities, and has an established foothold in the
industry. In addition to organize user conferences and providing online
resources for learning and using Bro, the creators of Bro also offer
enterprise-level commercial support.
With version 2.4, the Bro
development team integrated a new communication library based on CAF called
Broker (not to be confused with brokers in
CAF). Currently, this new communication layer is shipped as beta release and
needs to be enabled explicitly during build. Broker will become a mandatory
dependency in future Bro versions and replace the current communication and
serialization system.
In this interview, we have the pleasure to talk to the core development and
research team primarily located at the International Computer Science
Institute (ICSI) in Berkeley, California.
The Interview
CAF Team: Dear Bro team, thank you for giving us the opportunity for
this interview. The original paper describing Bro was released in 1999.
This is a very long time for a software code base and clearly speaks for
its quality. What is your secret?
Bro Team: When Vern Paxson created the initial version Bro, he designed the
system out of practical experience and---as we can say in hindsight---came up
with the right abstractions in the system architecture, which at its core hasn't
changed since.
We also carefully try to avoid feature creep and only add new functionality when
finding convincing use cases, which often involves discussion. While this
sometimes comes at the of cost development speed, it often helps us to make
strategically viable decisions in the long term.
CAF Team: Bro is a security-critical software and network operators
around the world rely on it. Changing a key component like the
communication system is not something that you do without having a good
reason. What was your motivation to start developing a new communication
backend from scratch?
Bro Team: To keep monitoring the ever-growing network uplinks at line rate
today (10, 40, or even 100 Gbps), the traffic needs to be distributed across
several physical systems. Logs are sent back to a single system, where they need
to be quickly and reliably written out. In addition, certain types of analysis
are distributed across all of the nodes (e.g. scan detection) and stress the
communications framework.
Our existing communication framework starts to show its age: there exist race
conditions with synchronization of high-level state, it lacks a persistence
component, the pub/sub data flow cannot be controlled in a fine-grained way, the
implementation is complex and inefficient, and we have to maintain two
independent implementations: there exists a separate C library (Broccoli) to
allow external applications to interact with Bro.
CAF Team: What goals did you set for the new communication system? What do
you want to achieve with the system in the long run?
Bro Team: Ultimately we want to "crack open" the boundaries of what
constitutes Bro and who can communicate with it. We also want to consolidate our
existing implementation into a single library, which both Bro and external
applications can use. In the past, Bro spawned a separate child process for its
communication. Now we're just linking against a shared library---Broker---which
provides a uniform API to communication in the Bro ecosystem.
We want to create a platform where it's easy to communicate with Bro instances,
reconfigure them on the fly, and change their state not just from within Bro,
but from anywhere. Moreover, we aim to provide a more flexible pub/sub event
communication infrastructure.
CAF Team: Many challenges in software development arise in the
implementation step and are not obvious in the initial design phase.
What were the core issues and challenges you faced when implementing
Broker and how did CAF contribute to your solution?
Bro Team: From a high level, ripping out a communication infrastructure and
replacing it with a new one, without users even noticing, is a big challenge.
This means we have to be able to incrementally deploy Broker. We already shipped
Broker with Bro 2.4, but it's not yet enabled by default. However, our master
branch already relies on Broker, which means that 2.5 will come with Broker
enabled by default after we get enough feedback from our users and putting out
release candidates. The transition to C++11 so far caused most of the attention.
From the implementation side, we wanted to converge to a tight, minimal API that
proves powerful enough to cover our use cases. CAF gives us the flexibility we
need to hide a powerful asynchronous backend behind a blocking C API, but also
expose the asynchrony at at Broker's C++ API. Then there's the messaging aspect:
Broker is essentially a distributed pub/sub engine which naturally maps to the
abstractions CAF provides.
One of our biggest challenges involves bringing together asynchronous lookups
and type-erasure in the Bro's statically typed scripting language. For example,
when asking a remote data store for a value, the return type is not known a
priori. Fortunately, we already have proposal for adding pattern matching (note
to the security community: not regular expressions) for type-safe message
access.
CAF Team: Did you consider other frameworks? If yes, what convinced
you to use CAF instead?
Bro Team: We looked at other, more low-level messaging libraries. In
particular, we compared CAF to nanomsg. With CAF we found that we could express
the same idea in significantly less code because it comes with everything we
need of the box. CAF simply doesn't require any boilerplate and enabled us to
focus on the problem domain, as opposed to grappling with the implementation
details of messaging framework. After all, avoiding complexity and being able to
reason about both code and protocol was the primary motivator for rewriting our
communication layer.
The type-safe abstractions CAF provides on top of bare messaging made a huge
difference in productivity. One of our team members summarized it as "[..] it
didn't feel like I was writing code that attempts to implement a protocol as
it felt like writing code that is the protocol."
We also found that nanomsg's communication patterns, which represent one of its
key selling points, can be easily implemented in a few lines of code with CAF.
Orthogonal to that, CAF comes with a nice failure semantics (monitors & links)
which we haven't found in other frameworks.
Finally, if you didn't release CAF under a BSD (or equivalently permissive)
license, we couldn't even have considered it in the first place.
CAF Team: How were the reactions to CAF in your team so far?
Bro Team: Internally we had one CAF fan already who brought the actor model
to the attention of the team. After our comparative evaluation, we were all
excited to see such a clear winner and looking forward to seeing CAF perform in
more than just toy examples.
CAF Team: Can you tell us about your performance and scaling
requirements? Did CAF meet your expectations?
Bro Team: Broker enables us to reach a new horizon in terms of scaling. Bro
is one of the unique open system capable of monitoring 100 Gbps---a workload
which only a cluster of machines can stem. The worker nodes must send the logs
somewhere via Broker, while the messaging layer must not induce a high overhead
so that the nodes can focus on their traffic analysis.
In addition to the standard cluster for monitoring a single link, we have an
ongoing "deep cluster" project where multiple sensor nodes deep in the network
augment the traditional boarder-gateway monitoring. This entails deploying
hundreds and thousands of nodes at global scale.
Finally, Bro can instruct open-flow controllers to reconfigure network hardware,
e.g., to insert blocking rules or shunt flows. These use cases have tight
latency requirements, with Broker must meet.
We are still in the process of evaluating performance; things look good so far
but we expect to do more tuning as our users start to rely on it for operations.
CAF Team: The official announcement of Broker was at BroCon
2015. How did your
community react to your plans for the communication system? Did they see
the benefits immediately or did they object to changing critical
components and introducing CAF as a new long-term dependency?
Bro Team: Our users liked that Broker enables new ways of communicating with
Bro in the future. We're already receiving first questions about Broker on the
mailing list.
Fortunately, our community trusts us developers that we make the right strategic
decisions about Bro's future. So we haven't heard any critical voices about
introducing CAF as new dependency. In fact, moving to C++11 will allows us to
modernize Bro's code base itself.
CAF Team: Final question: if you were to decide what the next
feature of CAF would be, what would you have in mind?
Bro Team: In the near term, we want to migrate to typed actors so that we
can get a compile-time proof that our messaging protocol implements the spec
correctly. But CAF can do that already. In the short term, we want to use the
direct connection optimization for when distant siblings in a tree hierarchy
communicate. Further down the road, we're excited about the planned
introspective features, where CAF can report utilization of CPU I/O, which we
would like to use a basis for decisions to adapt our topology dynamically at
runtime. CAF's stateful and migratable actors seem to lay the foundation for
this capability.
CAF Team: Thank you very much for this interview and we wish you all
the great success for the next 15 years of Bro!
Special thanks go to Matthias Vallentin for introducing the teams to each
other. Matthias is a member of the Bro team as well as a long-time contributor
to CAF.
Links
Bro Project: https://www.bro.org
Bro Github: https://github.com/bro
Bro Twitter: @Bro_IDS
Broker: https://github.com/bro/broker
[Less]
|
|
Posted
almost 11 years
ago
For our second article in the spotlight series, we want to higlight the popular
open source network monitor Bro and talk to the core
development team in Berkeley, California.
Background: Bro(ker)
Bro is an open source network analysis
... [More]
framework, well grounded in 15 years of
research. While focusing on network security monitoring, Bro provides a
comprehensive platform for more general network traffic analysis as well. Bro’s
user community includes major universities, research labs, supercomputing
centers, open-science communities, and has an established foothold in the
industry. In addition to organize user conferences and providing online
resources for learning and using Bro, the creators of Bro also offer
enterprise-level commercial support.
With version 2.4, the Bro
development team integrated a new communication library based on CAF called
Broker (not to be confused with brokers in
CAF). Currently, this new communication layer is shipped as beta release and
needs to be enabled explicitly during build. Broker will become a mandatory
dependency in future Bro versions and replace the current communication and
serialization system.
In this interview, we have the pleasure to talk to the core development and
research team primarily located at the International Computer Science
Institute (ICSI) in Berkeley, California.
The Interview
CAF Team: Dear Bro team, thank you for giving us the opportunity for
this interview. The original paper describing Bro was released in 1999.
This is a very long time for a software code base and clearly speaks for
its quality. What is your secret?
Bro Team: When Vern Paxson created the initial version Bro, he designed the
system out of practical experience and—as we can say in hindsight—came up
with the right abstractions in the system architecture, which at its core hasn’t
changed since.
We also carefully try to avoid feature creep and only add new functionality when
finding convincing use cases, which often involves discussion. While this
sometimes comes at the of cost development speed, it often helps us to make
strategically viable decisions in the long term.
CAF Team: Bro is a security-critical software and network operators
around the world rely on it. Changing a key component like the
communication system is not something that you do without having a good
reason. What was your motivation to start developing a new communication
backend from scratch?
Bro Team: To keep monitoring the ever-growing network uplinks at line rate
today (10, 40, or even 100 Gbps), the traffic needs to be distributed across
several physical systems. Logs are sent back to a single system, where they need
to be quickly and reliably written out. In addition, certain types of analysis
are distributed across all of the nodes (e.g. scan detection) and stress the
communications framework.
Our existing communication framework starts to show its age: there exist race
conditions with synchronization of high-level state, it lacks a persistence
component, the pub/sub data flow cannot be controlled in a fine-grained way, the
implementation is complex and inefficient, and we have to maintain two
independent implementations: there exists a separate C library (Broccoli) to
allow external applications to interact with Bro.
CAF Team: What goals did you set for the new communication system? What do
you want to achieve with the system in the long run?
Bro Team: Ultimately we want to “crack open” the boundaries of what
constitutes Bro and who can communicate with it. We also want to consolidate our
existing implementation into a single library, which both Bro and external
applications can use. In the past, Bro spawned a separate child process for its
communication. Now we’re just linking against a shared library—Broker—which
provides a uniform API to communication in the Bro ecosystem.
We want to create a platform where it’s easy to communicate with Bro instances,
reconfigure them on the fly, and change their state not just from within Bro,
but from anywhere. Moreover, we aim to provide a more flexible pub/sub event
communication infrastructure.
CAF Team: Many challenges in software development arise in the
implementation step and are not obvious in the initial design phase.
What were the core issues and challenges you faced when implementing
Broker and how did CAF contribute to your solution?
Bro Team: From a high level, ripping out a communication infrastructure and
replacing it with a new one, without users even noticing, is a big challenge.
This means we have to be able to incrementally deploy Broker. We already shipped
Broker with Bro 2.4, but it’s not yet enabled by default. However, our master
branch already relies on Broker, which means that 2.5 will come with Broker
enabled by default after we get enough feedback from our users and putting out
release candidates. The transition to C++11 so far caused most of the attention.
From the implementation side, we wanted to converge to a tight, minimal API that
proves powerful enough to cover our use cases. CAF gives us the flexibility we
need to hide a powerful asynchronous backend behind a blocking C API, but also
expose the asynchrony at at Broker’s C++ API. Then there’s the messaging aspect:
Broker is essentially a distributed pub/sub engine which naturally maps to the
abstractions CAF provides.
One of our biggest challenges involves bringing together asynchronous lookups
and type-erasure in the Bro’s statically typed scripting language. For example,
when asking a remote data store for a value, the return type is not known a
priori. Fortunately, we already have proposal for adding pattern matching (note
to the security community: not regular expressions) for type-safe message
access.
CAF Team: Did you consider other frameworks? If yes, what convinced
you to use CAF instead?
Bro Team: We looked at other, more low-level messaging libraries. In
particular, we compared CAF to nanomsg. With CAF we found that we could express
the same idea in significantly less code because it comes with everything we
need of the box. CAF simply doesn’t require any boilerplate and enabled us to
focus on the problem domain, as opposed to grappling with the implementation
details of messaging framework. After all, avoiding complexity and being able to
reason about both code and protocol was the primary motivator for rewriting our
communication layer.
The type-safe abstractions CAF provides on top of bare messaging made a huge
difference in productivity. One of our team members summarized it as “[..] it
didn’t feel like I was writing code that attempts to implement a protocol as
it felt like writing code that is the protocol.”
We also found that nanomsg’s communication patterns, which represent one of its
key selling points, can be easily implemented in a few lines of code with CAF.
Orthogonal to that, CAF comes with a nice failure semantics (monitors & links)
which we haven’t found in other frameworks.
Finally, if you didn’t release CAF under a BSD (or equivalently permissive)
license, we couldn’t even have considered it in the first place.
CAF Team: How were the reactions to CAF in your team so far?
Bro Team: Internally we had one CAF fan already who brought the actor model
to the attention of the team. After our comparative evaluation, we were all
excited to see such a clear winner and looking forward to seeing CAF perform in
more than just toy examples.
CAF Team: Can you tell us about your performance and scaling
requirements? Did CAF meet your expectations?
Bro Team: Broker enables us to reach a new horizon in terms of scaling. Bro
is one of the unique open system capable of monitoring 100 Gbps—a workload
which only a cluster of machines can stem. The worker nodes must send the logs
somewhere via Broker, while the messaging layer must not induce a high overhead
so that the nodes can focus on their traffic analysis.
In addition to the standard cluster for monitoring a single link, we have an
ongoing “deep cluster” project where multiple sensor nodes deep in the network
augment the traditional boarder-gateway monitoring. This entails deploying
hundreds and thousands of nodes at global scale.
Finally, Bro can instruct open-flow controllers to reconfigure network hardware,
e.g., to insert blocking rules or shunt flows. These use cases have tight
latency requirements, with Broker must meet.
We are still in the process of evaluating performance; things look good so far
but we expect to do more tuning as our users start to rely on it for operations.
CAF Team: The official announcement of Broker was at BroCon
2015. How did your
community react to your plans for the communication system? Did they see
the benefits immediately or did they object to changing critical
components and introducing CAF as a new long-term dependency?
Bro Team: Our users liked that Broker enables new ways of communicating with
Bro in the future. We’re already receiving first questions about Broker on the
mailing list.
Fortunately, our community trusts us developers that we make the right strategic
decisions about Bro’s future. So we haven’t heard any critical voices about
introducing CAF as new dependency. In fact, moving to C++11 will allows us to
modernize Bro’s code base itself.
CAF Team: Final question: if you were to decide what the next
feature of CAF would be, what would you have in mind?
Bro Team: In the near term, we want to migrate to typed actors so that we
can get a compile-time proof that our messaging protocol implements the spec
correctly. But CAF can do that already. In the short term, we want to use the
direct connection optimization for when distant siblings in a tree hierarchy
communicate. Further down the road, we’re excited about the planned
introspective features, where CAF can report utilization of CPU I/O, which we
would like to use a basis for decisions to adapt our topology dynamically at
runtime. CAF’s stateful and migratable actors seem to lay the foundation for
this capability.
CAF Team: Thank you very much for this interview and we wish you all
the great success for the next 15 years of Bro!
Special thanks go to Matthias Vallentin for introducing the teams to each
other. Matthias is a member of the Bro team as well as a long-time contributor
to CAF.
Links
Bro Project: https://www.bro.org
Bro Github: https://github.com/bro
Bro Twitter: @Bro_IDS
Broker: https://github.com/bro/broker
[Less]
|
|
Posted
almost 11 years
ago
For our second article in the spotlight series, we want to higlight the popular
open source network monitor Bro and talk to the core
development team in Berkeley, California.
Background: Bro(ker)
Bro is an open source network analysis
... [More]
framework, well grounded in 15 years of
research. While focusing on network security monitoring, Bro provides a
comprehensive platform for more general network traffic analysis as well. Bro's
user community includes major universities, research labs, supercomputing
centers, open-science communities, and has an established foothold in the
industry. In addition to organize user conferences and providing online
resources for learning and using Bro, the creators of Bro also offer
enterprise-level commercial support.
With version 2.4, the Bro
development team integrated a new communication library based on CAF called
Broker (not to be confused with brokers in
CAF). Currently, this new communication layer is shipped as beta release and
needs to be enabled explicitly during build. Broker will become a mandatory
dependency in future Bro versions and replace the current communication and
serialization system.
In this interview, we have the pleasure to talk to the core development and
research team primarily located at the International Computer Science
Institute (ICSI) in Berkeley, California.
The Interview
CAF Team: Dear Bro team, thank you for giving us the opportunity for
this interview. The original paper describing Bro was released in 1999.
This is a very long time for a software code base and clearly speaks for
its quality. What is your secret?
Bro Team: When Vern Paxson created the initial version Bro, he designed the
system out of practical experience and---as we can say in hindsight---came up
with the right abstractions in the system architecture, which at its core hasn't
changed since.
We also carefully try to avoid feature creep and only add new functionality when
finding convincing use cases, which often involves discussion. While this
sometimes comes at the of cost development speed, it often helps us to make
strategically viable decisions in the long term.
CAF Team: Bro is a security-critical software and network operators
around the world rely on it. Changing a key component like the
communication system is not something that you do without having a good
reason. What was your motivation to start developing a new communication
backend from scratch?
Bro Team: To keep monitoring the ever-growing network uplinks at line rate
today (10, 40, or even 100 Gbps), the traffic needs to be distributed across
several physical systems. Logs are sent back to a single system, where they need
to be quickly and reliably written out. In addition, certain types of analysis
are distributed across all of the nodes (e.g. scan detection) and stress the
communications framework.
Our existing communication framework starts to show its age: there exist race
conditions with synchronization of high-level state, it lacks a persistence
component, the pub/sub data flow cannot be controlled in a fine-grained way, the
implementation is complex and inefficient, and we have to maintain two
independent implementations: there exists a separate C library (Broccoli) to
allow external applications to interact with Bro.
CAF Team: What goals did you set for the new communication system? What do
you want to achieve with the system in the long run?
Bro Team: Ultimately we want to "crack open" the boundaries of what
constitutes Bro and who can communicate with it. We also want to consolidate our
existing implementation into a single library, which both Bro and external
applications can use. In the past, Bro spawned a separate child process for its
communication. Now we're just linking against a shared library---Broker---which
provides a uniform API to communication in the Bro ecosystem.
We want to create a platform where it's easy to communicate with Bro instances,
reconfigure them on the fly, and change their state not just from within Bro,
but from anywhere. Moreover, we aim to provide a more flexible pub/sub event
communication infrastructure.
CAF Team: Many challenges in software development arise in the
implementation step and are not obvious in the initial design phase.
What were the core issues and challenges you faced when implementing
Broker and how did CAF contribute to your solution?
Bro Team: From a high level, ripping out a communication infrastructure and
replacing it with a new one, without users even noticing, is a big challenge.
This means we have to be able to incrementally deploy Broker. We already shipped
Broker with Bro 2.4, but it's not yet enabled by default. However, our master
branch already relies on Broker, which means that 2.5 will come with Broker
enabled by default after we get enough feedback from our users and putting out
release candidates. The transition to C++11 so far caused most of the attention.
From the implementation side, we wanted to converge to a tight, minimal API that
proves powerful enough to cover our use cases. CAF gives us the flexibility we
need to hide a powerful asynchronous backend behind a blocking C API, but also
expose the asynchrony at at Broker's C++ API. Then there's the messaging aspect:
Broker is essentially a distributed pub/sub engine which naturally maps to the
abstractions CAF provides.
One of our biggest challenges involves bringing together asynchronous lookups
and type-erasure in the Bro's statically typed scripting language. For example,
when asking a remote data store for a value, the return type is not known a
priori. Fortunately, we already have proposal for adding pattern matching (note
to the security community: not regular expressions) for type-safe message
access.
CAF Team: Did you consider other frameworks? If yes, what convinced
you to use CAF instead?
Bro Team: We looked at other, more low-level messaging libraries. In
particular, we compared CAF to nanomsg. With CAF we found that we could express
the same idea in significantly less code because it comes with everything we
need of the box. CAF simply doesn't require any boilerplate and enabled us to
focus on the problem domain, as opposed to grappling with the implementation
details of messaging framework. After all, avoiding complexity and being able to
reason about both code and protocol was the primary motivator for rewriting our
communication layer.
The type-safe abstractions CAF provides on top of bare messaging made a huge
difference in productivity. One of our team members summarized it as "[..] it
didn't feel like I was writing code that attempts to implement a protocol as
it felt like writing code that is the protocol."
We also found that nanomsg's communication patterns, which represent one of its
key selling points, can be easily implemented in a few lines of code with CAF.
Orthogonal to that, CAF comes with a nice failure semantics (monitors & links)
which we haven't found in other frameworks.
Finally, if you didn't release CAF under a BSD (or equivalently permissive)
license, we couldn't even have considered it in the first place.
CAF Team: How were the reactions to CAF in your team so far?
Bro Team: Internally we had one CAF fan already who brought the actor model
to the attention of the team. After our comparative evaluation, we were all
excited to see such a clear winner and looking forward to seeing CAF perform in
more than just toy examples.
CAF Team: Can you tell us about your performance and scaling
requirements? Did CAF meet your expectations?
Bro Team: Broker enables us to reach a new horizon in terms of scaling. Bro
is one of the unique open system capable of monitoring 100 Gbps---a workload
which only a cluster of machines can stem. The worker nodes must send the logs
somewhere via Broker, while the messaging layer must not induce a high overhead
so that the nodes can focus on their traffic analysis.
In addition to the standard cluster for monitoring a single link, we have an
ongoing "deep cluster" project where multiple sensor nodes deep in the network
augment the traditional boarder-gateway monitoring. This entails deploying
hundreds and thousands of nodes at global scale.
Finally, Bro can instruct open-flow controllers to reconfigure network hardware,
e.g., to insert blocking rules or shunt flows. These use cases have tight
latency requirements, with Broker must meet.
We are still in the process of evaluating performance; things look good so far
but we expect to do more tuning as our users start to rely on it for operations.
CAF Team: The official announcement of Broker was at BroCon
2015. How did your
community react to your plans for the communication system? Did they see
the benefits immediately or did they object to changing critical
components and introducing CAF as a new long-term dependency?
Bro Team: Our users liked that Broker enables new ways of communicating with
Bro in the future. We're already receiving first questions about Broker on the
mailing list.
Fortunately, our community trusts us developers that we make the right strategic
decisions about Bro's future. So we haven't heard any critical voices about
introducing CAF as new dependency. In fact, moving to C++11 will allows us to
modernize Bro's code base itself.
CAF Team: Final question: if you were to decide what the next
feature of CAF would be, what would you have in mind?
Bro Team: In the near term, we want to migrate to typed actors so that we
can get a compile-time proof that our messaging protocol implements the spec
correctly. But CAF can do that already. In the short term, we want to use the
direct connection optimization for when distant siblings in a tree hierarchy
communicate. Further down the road, we're excited about the planned
introspective features, where CAF can report utilization of CPU I/O, which we
would like to use a basis for decisions to adapt our topology dynamically at
runtime. CAF's stateful and migratable actors seem to lay the foundation for
this capability.
CAF Team: Thank you very much for this interview and we wish you all
the great success for the next 15 years of Bro!
Special thanks go to Matthias Vallentin for introducing the teams to each
other. Matthias is a member of the Bro team as well as a long-time contributor
to CAF.
Links
Bro Project: https://www.bro.org
Bro Github: https://github.com/bro
Bro Twitter: @Bro_IDS
Broker: https://github.com/bro/broker
[Less]
|