-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deprecates Sender for much simpler BytesMessageSender (#244)
async reporters never actually use the async code of the senders. The async side was only used by zipkin-server, as the async reporter design intentionally uses a blocking loop to flush the span backlog. So, this makes things simpler by only requiring a blocking implementation: `BytesMessageSender.send` (chosen to not create symbol collisions and similar to `BytesMessageEncoder`. The side effect is that new senders can use this interface and completely avoid the complicated `Call` then `execute` chain, deferring to whatever the library-specific blocking path is. As older spring libraries like sleuth may not upgrade, this maintains the old types until reporter 4. However, new senders can simply implement the new type and be done with it. Signed-off-by: Adrian Cole <[email protected]>
- Loading branch information
1 parent
2dbac71
commit 22b0e37
Showing
63 changed files
with
931 additions
and
503 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# zipkin-reporter rationale | ||
|
||
## Sending an empty list is permitted | ||
|
||
Historically, we had a `Sender.check()` function for fail fast reasons, but it was rarely used and | ||
rarely implemented correctly. In some cases, people returned `OK` having no knowledge of if the | ||
health was good or not. In one case, Stackdriver, a seemingly good implementation was avoided for | ||
directly sending an empty list of spans, until `check()` was changed to do the same. Rather than | ||
define a poorly implementable `Sender.check()` which would likely still require sending an empty | ||
list, we decided to document a call to send no spans should pass through. | ||
|
||
Two known examples of using `check()` were in server modules that forward spans with zipkin reporter | ||
and finagle. `zipkin-finagle` is no longer maintained, so we'll focus on the server modules. | ||
|
||
zipkin-stackdriver (now zipkin-gcp) was both important to verify and difficult to implement a | ||
meaningful `check()`. First attempts looked good, but would pass even when users had no permission | ||
to write spans. For this reason, people ignored the check and did out-of-band sending zero spans to | ||
the POST endpoint. Later, this logic was made the primary impl of `check()`. | ||
|
||
In HTTP senders a `check()` would be invalid for non-intuitive reasons unless you also just posted | ||
no spans. For example, while zipkin has a `/health` endpoint, most clones do not implement that or | ||
put it at a different path. So, you can't check with `/health` and are left with either falsely | ||
returning `OK` or sending an empty list of spans. | ||
|
||
Note that zipkin server does obviate calls to storage when incoming lists are empty. This is not | ||
just for things like this, but 3rd party instrumentation which bugged out and sent no spans. | ||
|
||
Messaging senders came close to implementing health except would suffer similar problems as | ||
Stackdriver did. For example, verifying broker connectivity doesn't mean the queue or topic works. | ||
While you can dig around and solve this for some brokers, it ends up the same situation. | ||
|
||
Another way could be to catch an exception from a prior "POST", and if that failed, return a | ||
corresponding status. This could not be for fail-fast because the caller wouldn't have any spans to | ||
send, yet. It is complicated code for a function uncommon in instrumentation and the impl would be | ||
hard to reason with concurrently. | ||
|
||
The main problem is that we used the same `Component` type in reporter as we did for zipkin server, | ||
which defined `check()` in a hardly used and hardly implementable way except sending no spans. | ||
|
||
We had the following choices: | ||
|
||
* force implementation of `check()` knowing its problems and that it is usual in instrumentation | ||
* document that implementors can skip `send(empty)` even though call sites use this today | ||
* document that you should not skip `send(empty)`, so that the few callers can use it for fail-fast | ||
|
||
The main driving points were how niche this function is (not called by many, or on interval), | ||
and how much work it is to implement a `check()` vs allowing an empty send to proceed. In the | ||
current code base, the only work required for the latter was documentation, as all senders would | ||
pass an empty list. Secondary driving force was that the `BytesMessageSender` main goal is easier | ||
implementation and re-introducing a bad `check()` api gets in the way of this. | ||
|
||
Due to the complexity of this problem, we decided that rather to leave empty undefined, document | ||
sending empty is ok. This allows a couple users to implement a fail-fast in a portable way, without | ||
burdening implementers of `BytesMessageSender` with an unimplementable or wrong `check()` function | ||
for most platforms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.