Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

add OpenTracing-Examples #174

Merged
merged 7 commits into from
Sep 15, 2017
Merged

add OpenTracing-Examples #174

merged 7 commits into from
Sep 15, 2017

Conversation

malafeev
Copy link

@malafeev malafeev commented Sep 5, 2017

move examples from https://github.com/opentracing-contrib/java-examples to be part of
opentracing-java

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling d20f546 on malafeev:master into 578d4e7 on opentracing:master.

@yurishkuro
Copy link
Member

could we add a readme at the module level briefly explaining what each example represents?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling 744ebd8 on malafeev:master into 578d4e7 on opentracing:master.

@objectiser
Copy link
Contributor

Instead of just moving them into this repo as "examples", do we want to take this opportunity to start some form of conformance test suite? Could be based on these examples initially and changed over time if necessary to ensure testing all aspects of the API.

@malafeev
Copy link
Author

malafeev commented Sep 7, 2017

These examples could evolve into

conformance test suite

some day.
Now it is more for testing different api proposals (like get rid of Continuation :) ).
If somebody proposes such great change let's make examples work first :)

@carlosalberto
Copy link
Collaborator

some day. Now it is more for testing different api proposals

I agree on this point with @malafeev - I think at this time they are a testbed for such changes, and not much of actual tests (and thus the listing of specific use cases there, and not the common ones).

@tedsuo
Copy link
Member

tedsuo commented Sep 8, 2017

I like the idea @objectiser; I'd like to see us build out a test harness for tracers to verify that they conform to the spec properly. Perhaps durning or after the release candidate process we can work on this?

The immediate concern that examples were created to solve is that we need a place to discuss the API using code. If we encounter a usecase during the release candidate process where we feel the API is incomplete or ambiguous, we need a way to record this fact for all to see. So this is about "correctness of the API" itself as opposed to "correctness of an implementation of the API".

Personally, I think we can continue to push and change this example/test code as patch versions to the API, so we don't need to get it perfect on the first shot and can merge this in. If that approach is problematic, we should leave it in ot-contrib until we work it out.

Copy link
Member

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

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

I did a partial review. I would like to see more comments, why something is bad and something good.

Could we get rid of all unnecessary waits/sleeps and joins with magic constants? It is just a distraction.

</dependency>

<dependency>
<groupId>com.jayway.awaitility</groupId>
Copy link
Member

Choose a reason for hiding this comment

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

Use new version https://mvnrepository.com/artifact/org.awaitility/awaitility/3.0.0 (it's under slightly different groupId/artifactId)

Copy link
Member

Choose a reason for hiding this comment

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

Please define version in properties

Copy link
Author

Choose a reason for hiding this comment

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

done

</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
Copy link
Member

Choose a reason for hiding this comment

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

can we use just System.out.print() for simplicity?

Copy link
Author

Choose a reason for hiding this comment

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

yes, but I wanted to print thread name, time, don't use ugly string concatenation...

}
}
if (found.size() > 1) {
throw new RuntimeException("Ups, it's too much");
Copy link
Member

Choose a reason for hiding this comment

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

A more meaningful message would be good

Copy link
Member

Choose a reason for hiding this comment

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

IllegalArgumentException is more suitable for this

Copy link
Author

Choose a reason for hiding this comment

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

done

ActiveSpan activeSpan = continuation.activate();

try {
TimeUnit.SECONDS.sleep(1);
Copy link
Member

Choose a reason for hiding this comment

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

Is this necessary? Just leave a comment in the middle that it wraps some logic.

Copy link
Author

Choose a reason for hiding this comment

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

added commend

import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;

public class TestCallback {
Copy link
Member

Choose a reason for hiding this comment

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

Could you please use the Test suffix like it is in other tests in this repo?

}

assertNotEquals(finished.get(0).context().traceId(), finished.get(1).context().traceId());
assertEquals(finished.get(0).parentId(), finished.get(1).parentId());
Copy link
Member

Choose a reason for hiding this comment

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

I think that these two last lines are distracting. I would rather see asset on 0 it's more explicit.

}


public Future<Object> send(final Object message) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: return String

Copy link
Author

Choose a reason for hiding this comment

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

done

}

/**
* Solution is bad because parent is per client (we don't have better choice)
Copy link
Member

Choose a reason for hiding this comment

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

Explain it better, that happened, why it is bad

Copy link
Author

Choose a reason for hiding this comment

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

done


for (int i = 0; i < 2; i++) {
assertEquals(true, spans.get(2).finishMicros() >= spans.get(i).finishMicros());
assertEquals(spans.get(2).context().traceId(), spans.get(i).context().traceId());
Copy link
Member

Choose a reason for hiding this comment

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

nit: create TestUtils.assertSameTrace(List<MockSpan>)

Copy link
Author

Choose a reason for hiding this comment

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

done


Examples of common instrumentation patterns:

- **activate_deactivate** - callbacks finish at some time.
Copy link
Member

Choose a reason for hiding this comment

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

Could we create some categories? e.g. one related to client-server other to callbacks and order them from the simplest to more complex use cases?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling 2fc00b0 on malafeev:master into 431ebc3 on opentracing:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling cce6752 on malafeev:master into 431ebc3 on opentracing:master.

@pavolloffay
Copy link
Member

@malafeev I have a meta request. Could you please clean the sources:

  • do not use .join(SOME_MAGIC_NUMBER)
  • do not use future.get(MAGIC, time_unit)
  • use comments consistently (do not mix /**/ // and pay attention to indentation).
  • do not use sleep(ms) when it's not needed. In the most places, it's not needed. It's just a noise which makes it harder to read, nothing more.

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
Copy link
Member

Choose a reason for hiding this comment

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

Define versions in parent pom

Copy link
Author

Choose a reason for hiding this comment

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

ok

import java.util.concurrent.TimeUnit;

/**
* Callback which executed at some time. We don't know when it is started, when it is
Copy link
Member

Choose a reason for hiding this comment

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

I think this comment is misleading. It depends on how the callback is executed.

Copy link
Author

Choose a reason for hiding this comment

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

Idea is to show case when callback is executed at some time and we don't know when it is started, completed, no status.

Copy link
Member

Choose a reason for hiding this comment

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

My point is that this comment is at wrong place.

public void test() throws Exception {
Thread entryThread = entryThread();
entryThread.start();
entryThread.join(10_000);
Copy link
Member

Choose a reason for hiding this comment

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

Why this magic number?Applies to a lot of places in this PR.

Copy link
Member

Choose a reason for hiding this comment

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

That thread will end, no need to specify max wait time

Copy link
Author

Choose a reason for hiding this comment

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

ok

private int getTestTagsCount(MockSpan mockSpan) {
Map<String, Object> tags = mockSpan.tags();
int tagCounter = 0;
for (String tagKey : tags.keySet()) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: mockSpan.tags().keySet()

Copy link
Author

Choose a reason for hiding this comment

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

ok

assertEquals(parentSpan.context().spanId(), spans.get(i).parentId());
}

assertNull(tracer.activeSpan());
Copy link
Member

Choose a reason for hiding this comment

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

This is just redundant noise. Are you trying to test active span source in MockTracer works?

Copy link
Author

Choose a reason for hiding this comment

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

maybe client activated span and not deactivated? better to test than assume.

}

private static MockSpan getOneByOperationName(List<MockSpan> spans, String name) {
List<MockSpan> found = new ArrayList<>();
Copy link
Member

Choose a reason for hiding this comment

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

you don't need a list to do this.

Copy link
Author

Choose a reason for hiding this comment

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

done

}
}
if (found.size() > 1) {
throw new RuntimeException("Ups, it's too much");
Copy link
Member

Choose a reason for hiding this comment

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

IllegalArgument ex is better

try (ActiveSpan childSpan1 = tracer.buildSpan("task1").startActive()) {
sleep(55);
}
span.capture(); // Workaround, prevent parentSpan from being finished here.
Copy link
Member

Choose a reason for hiding this comment

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

This is anti-pattern. Do we want to have anti-patterns in examples? There should be continuation create for each runnable. e.g. https://paste.fedoraproject.org/paste/SvU3kpGwJbMqP2HTI6mi9A

Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea for this test sample was to have a 'master' Span whose lifetime is not tied to any children - hence we couldn't pass a Continuation, as creating them would increment the refcount for them.

Then again, another option to prevent this usage would be to simply have them create a Continuation and don't close the 'master' ActiveSpan (which, I think, you will definitely prefer ;) )

Copy link
Member

Choose a reason for hiding this comment

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

These examples need more explanatory comments. Especially for this anti-patterns, explain why it is written like it is.

// Alternative to calling makeActive() is to pass it manually to asChildOf() for each created Span.
try (ActiveSpan span = tracer.makeActive(parentSpan)) {
try (ActiveSpan childSpan1 = tracer.buildSpan("task1").startActive()) {
sleep(55);
Copy link
Member

Choose a reason for hiding this comment

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

you don't really need a sleep here

- **late_span_finish** - late parent span finish
- **listener_per_request** - one listener per request
- **multiple_callbacks** - multiple callbacks
- **nested_callbacks** - nested callbacks
Copy link
Member

Choose a reason for hiding this comment

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

Create a section for async/callbacks. Better comments would be appreciated.

multiple_callbacks - multiple callbacks`. e.g. how it differs from nested ones.

Copy link
Contributor

@bhs bhs left a comment

Choose a reason for hiding this comment

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

(thanks!)

@@ -0,0 +1,14 @@
# OpenTracing-Java examples
Copy link
Contributor

Choose a reason for hiding this comment

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

We need a "Why does this exist" sort of thing... Could just be ## Module purpose or whatever. My TL;DR is (1) something to test API changes against, (2) something to look at for common instrumentation patterns, (3) something to use for Tracer regression testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

... oh, and let's make a pointer in the main OT-Java README, too.

Copy link
Author

Choose a reason for hiding this comment

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

should be pointer under "Development" section?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling ed08547 on malafeev:master into 431ebc3 on opentracing:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling 74da38a on malafeev:master into 431ebc3 on opentracing:master.

import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;

public class TestScheduledActions {
Copy link
Member

Choose a reason for hiding this comment

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

Could you please rename test classes to align with naming convention used in this repo. All other test files are named WhateverTest

@coveralls
Copy link

Coverage Status

Coverage remained the same at 74.074% when pulling b4e547d on malafeev:master into 431ebc3 on opentracing:master.

@tedsuo
Copy link
Member

tedsuo commented Sep 14, 2017

@pavolloffay @malafeev is this good enough to merge at this point? There are people waiting to add more test cases. If it's just style tweaks and documentation left to work on, can we merge and do that as subsequent PRs?

@malafeev
Copy link
Author

I think it could be merged although more explanations should be added to examples.

@pavolloffay
Copy link
Member

Yes, it looks better and cleaner, however, I still think it needs more comments. let's not block others and merge this.

@tedsuo tedsuo merged commit 767f716 into opentracing:master Sep 15, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants