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

Circular dependency with noop.js #70

Open
felixfbecker opened this issue Apr 2, 2017 · 8 comments
Open

Circular dependency with noop.js #70

felixfbecker opened this issue Apr 2, 2017 · 8 comments

Comments

@felixfbecker
Copy link
Contributor

The circular dependency of Tracer -> noop -> Tracer is definitely a code smell that is worked around here with an initialize function that needs to be called. Why not simply remove the noop.js file, and let the tracer, span etc files export a noop instance (if we need an eagerly instantiated instance at all)?

@yurishkuro
Copy link
Member

Good point. Could be a remnant of the original design that required the use of delegate, which was later change to define just an API that can be implemented independently.

I think the dependency should be

  • Tracer API
  • Noop tracer implements Trace API
  • Global tracer wrapper with a delegate of type Tracer
  • Global tracer by default initialized to Noop tracer.

@tedsuo
Copy link
Member

tedsuo commented May 2, 2017

Why do we need a delegate for the GlobalTracer? Can we just ensure it's always initialized to a NoopTracer and avoid the delegation overhead?

import Tracer from './tracer';

const noopTracer = new Tracer();
let _globalTracer: noopTracer;

export function initGlobalTracer(tracer: Tracer): void {
    _globalTracer = tracer || noopTracer;
}

/**
 * Returns the global tracer.
 */
export function globalTracer(): Tracer {
    return _globalTracer;
}

@felixfbecker
Copy link
Contributor Author

Your example still requires `initGlobalTracer to be called once, but you can change it if you initialise it directly. Pretty sure it would work.

@tedsuo
Copy link
Member

tedsuo commented May 2, 2017

Only thing I can think of: the delegate would let you swap out the tracer reference later, in case you already stored the reference somewhere else before the tracer was initialized. I think in my solution some portion of your code could get stuck with a noopTracer by accident due to init ordering.

I am concerned that calling apply the way we do in the delegate will prevent JS optimizations from occurring, so if we can get out from under the delegation it would be nice.

@felixfbecker
Copy link
Contributor Author

Why do you think .apply() would deoptimize the function?
https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#what-is-safe-arguments-usage

@tedsuo
Copy link
Member

tedsuo commented May 2, 2017

Ah, I see I am incorrect. I thought apply had similar issues to bind and prevented object caching.

@bhs
Copy link
Contributor

bhs commented May 28, 2017

@yurishkuro

I think the dependency should be

  • Tracer API
  • Noop tracer implements Trace API
  • Global tracer wrapper with a delegate of type Tracer
  • Global tracer by default initialized to Noop tracer.

SGTM – I'll try to make this happen or find someone who can make this happen. :)

@felixfbecker
Copy link
Contributor Author

Currently there are no interfaces to implement, the Tracer, Span etc classes actually already act as a noop implementation. I use successfully like that: https://sourcegraph.com/github.com/sourcegraph/javascript-typescript-langserver/-/blob/src/project-manager.ts#L834-835
I allow to pass a parent span, and default it to a noop span if none is passed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants