-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v2 proposal #24
Comments
Hello, I agree that the client needs a v2 version. When I started working on it, I didn't know Go at all (now, I'm much better :p). Thanks you for your proposals, I will think about it next week :) |
I just pushed a prototype implementation for a v2. Only TCPClient is implemented using a buffered sender. The code is here. You can run You should see something like this:
Tell me what you think :) |
Thanks for you work. here are some comments:
Not needed for UDP.
I like being able to choose when to define a client and when to start it. Sometimes, it's not at the same time. I would keep the Connect() method.
I often need to send events to Riemann without the hostname set, so I would not set the hostname by default.
I will try to find the time next week to work on it too. |
Aloha,
I believe you appreciate to keep control on when the client should connect. So you can instantiate a client somewhere in your code and then later, connect to Riemann and then do some real work. The idea behind this is not to connect when it is not needed I think. If the client lazily connects to Riemann it achieves the exact same goal while masking the implementation so users do not even have to care about connecting to Riemann. If you want to send some events then the client should connect if not already connected and if you want to query the index then the client should connect right before sending the query. By default the client could keep the connection open and reuse it as much as possible and automatically reconnect when needed so the user does not even have to care about this.
That's perfect :)
Indeed. It really depends on the use case. If a user wants to send Riemann events at a low rate or from times to times then yes it is required to check the response Riemann returns in order to give the user a chance to act on this response, maybe retry if the send fails or anything else a user may need. Another use case (mine for example) is to send events to Riemann at a very high rate. Basically my use case will literally flood Riemann with events. Which means that I can not afford to check whether or not the event is correctly processed by Riemann as I expect it to be the case and if I had to check Riemann's response every time as this will kill the sending throughput. This indeed poses the problem of backpressure you describes below. The good news is that I believe there is a way to solve both problems simply by providing a buffered sender (sends in bulk and ignore Riemann's response) and a non buffered one (sends events possibly one by one and check Riemman's response and returns it to the user).
Maybe there is a way to let the client handle backpressure. Here is a possible strategy. In a separate connection, the client could poll
Never used it but why not :)
Ha, indeed. But then is it a context per event which is to be sent or a context per bulk sent ?
Cool :) |
Hi there, I spotted a few problems with the current implementation which led me to write a specification for a possible v2. Here it is
Table of Contents
New public API
There are only two available clients: TCP or UDP.
TLS becomes an optional configuration which can be injected to either the TCP or UDP client.
No more
Connect()
method. Connection must be lazily handled by the client.It is up to the caller's responsability to call
Close()
when required.examples below.
A non TLS TCP client
A non TLS UDP client
A TLS enabled TCP client
A TLS enabled UDP client
If that's too complex for users to implement all these steps for TLS client it is trivial to provide a helper function such as.
So it can be used like this:
(The same thing can be done for a UDP builder)
New Event type
The current
Event
type is:There are two problems with it:
Event.Ttl
should be atime.Duration
so it is easier to express how longan
Event
will survive in Riemman's indexEvent.Metric
generates all sort of complexities when marshalling andrequires using Golang's reflection which is complex and slow
The new proposed
Event
is :According to Riemman's proto definition an event only supports one of the the following types:
So I propose to directly map :
Event.MetricInt64
toEvent.metric_sint64
Event.MetricFloat32
toEvent.metric_d
Event.MetricFloat64
toEvent.metric_f
And let the user decide which must be used and accept the possible loss that goes along with it for example when sending an
uint64
.By doing this we avoid using Golang's reflection and simplify the marshaling process by using the first non
nil
value amongMetric(Int64|Float32|Float64)
.Unless there is a high added value to sort
Event.Attributes
I propose not to sort them and send them as is.Event.Host
can be defaulted toos.Hostname()
but we should state in the documentation that this will generate anopenat
syscall (at least onLinux), more specifically :
openat(AT_FDCWD, "/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC ...)
for every newEvent
.A buffered sender
I propose to always send events in bulk. The idea behind this buffered (bulked) sender is to reduce roundtrips between Riemman and the sender as much as
possible in order to maximize thoughput while still keeping a pretty high send rate.
Here is a prototype implementation below:
What do you think ?
:)
The text was updated successfully, but these errors were encountered: