You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by GitBox <gi...@apache.org> on 2019/03/11 02:27:01 UTC

[GitHub] [incubator-skywalking] BFergerson edited a comment on issue #2341: Support plugin for Vert.x

BFergerson edited a comment on issue #2341: Support plugin for Vert.x
URL: https://github.com/apache/incubator-skywalking/issues/2341#issuecomment-471383541
 
 
   I had a lightbulb moment when you said the key was I was creating spans on a shared thread. I'm pretty sure you're absolutely right. Unfortunately, I think that's the only way to use Vert.x. Everything that runs in the verticle is run on the event loop and in my situation, there is only a single event loop. That's what I'm seeing locally as I debug the creation of the spans. The thread is always `vert.x-eventloop-thread-0`.
   
   I should have included some Vert.x code to begin with to open this discussion. I've included some below and described the steps the code takes and the steps I take to trace it.
   
   ```java
   public class Sender extends AbstractVerticle {
   
       public static void main(String[] args) {
           Vertx vertx = Vertx.vertx();
           vertx.deployVerticle(new Sender());
       }
   
       @Override
       public void start() {
           Router router = Router.router(vertx);
           router.route().handler(BodyHandler.create());
           router.get("/products/:productID").handler(this::handleGetProduct);
           vertx.createHttpServer().requestHandler(router).listen(8080);
   
           //vertx.setPeriodic(1000, v -> callGetProduct());
           callGetProduct();
       }
   
       private void callGetProduct() {
           HttpClient httpClient = vertx.createHttpClient();
           httpClient.getNow(8080, "localhost", "/products/test",
                   new Handler<HttpClientResponse>() {
   
                       @Override
                       public void handle(HttpClientResponse httpClientResponse) {
                           System.out.println("Got response");
                       }
                   });
       }
   
       private void handleGetProduct(RoutingContext routingContext) {
           HttpServerResponse response = routingContext.response();
           vertx.setTimer(4000, it -> {
               response.setStatusCode(200).end("Done");
           });
       }
   }
   ```
   
   I've tried to keep it as simple as possible and I think I'm creating the right spans at the right places.
    - I have an `HttpClient` which calls a `GET` request on `/products/test`. This opens a `ExitSpan`.
    - This request is received by `handleGetProduct`. This opens a `EntrySpan`.
    - The response is delayed by 4 seconds and then responds with "Done". This closes the `EntrySpan`.
    - The response is received by `handle`. This closes the `ExitSpan`.
   
   The locations I'm doing the opening and closing of spans seems correct to me as well.
    - The `HttpClient` sends the `GET` request by calling `HttpClientRequestImpl.end()`. I take the `ContextCarrier` and inject it into the header and open the `ExitSpan`. I also assign the `ContextSnapshot` to the request (via `EnhancedInstance`) for closing later.
    - The `GET` request is receieved and sent to the target method via `HttpServerRequestImpl.doEnd()`. I remove the headers to rebuild the `ContextCarrier` and open a `EntrySpan`. I also assign the `ContextSnapshot` to the response (via `EnhancedInstance`) for closing later.
    - 4 seconds pass
    - I pull the `ContextSnapshot` from the response (via `EnhancedInstance`) and close the `EntrySpan` once `HttpServerResponseImpl.end()` is called as this signifies the response has been written.
    - I pull the `ContextSnapshot` from the request (via `EnhancedInstance`) and close the `ExitSpan` once `HttpClientRequestImpl.doHandleResponse()` is called as this signifies a request has been replied to.
   
   Again, this all works when I just go through this flow once. The single call in the code to `callGetProduct();` fulfills this scenario. It's once `//vertx.setPeriodic(1000, v -> callGetProduct());` is uncommented that it starts acting up. As you can see, `setPeriodic` makes the call to `callGetProduct` every second. This means that I won't have the previous trace closed by the time the next one starts.
   
   Given that Vert.x is running everything on a shared thread, and the goal is to not create spans on a shared thread, what's my move here?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services