Skip to content

plugin-user-interaction integrated into vue.js #820

@snake-ch

Description

@snake-ch
  • This only affects the JavaScript OpenTelemetry library
  • This may affect other libraries, but I would like to get opinions here first

I try to use user-interaction plugin with vue.js, there is something wrong with tracing. I read the source code of the plugin. it seems that async operation counter +1 when invoke patchScheduleTask() and -1 when invoke patchRunTask() and then finish span when all tasks done.

The question is : is it possible an async operation scheduled in a zoneTask and invoke its callback in another?

<div id="root" @click="hello">{{ msg }}</div>
var vm = new Vue({
  el: '#root',
  data: {
    msg : ''
  }
  methods:{
    ...
   
    function hello(){
      // 1. dom update
      this.msg = "hello world"
      // 2. async operation
      setTimeout(() => {}, 0);
    }
    
    ...
  }
})

In user-interaction-plugin, click event listener callback(here is hello()) will run in a new zone, then patchScheduleTask() will detect setTimeout(...), patchRunTask() will invoke its callback fn, right?
when hello() function done, vue will notify watcher to update DOM, it generates a Promise outside hello() function, with DOM update callback inside.

I print the params defined in patchScheduleTask() and patchRunTask() log message, schedule and run with different zoneTask, and _shouldCountTask() followed, span with number of task is not correct.

_patchZoneScheduleTask(), _patchZoneRunTask(), _patchZoneCancelTask(), I replace current zone global to the zone.js callback inner one:

  private _patchZoneScheduleTask() {
    const plugin = this;
    return (original: any) => {
      return function patchScheduleTask<T extends Task>(
        this: Zone,
        task: AsyncTask
      ) {
        // const currentZone = Zone.current;
        const currentZone = this;
        const currentSpan: types.Span = currentZone.get(ZONE_SCOPE_KEY);
        if (currentSpan && plugin._shouldCountTask(task, currentZone)) {
          plugin._incrementTask(currentSpan);
          plugin._checkForTimeout(task, currentSpan);
        }
        return original.call(this, task) as T;
      };
    };
  }

it works, is it the right thing to do?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions