jeudi 3 novembre 2016

Strange caching problems when extending NodeJS Proxy

Driven by the desire of having a 'true' Proxy Class in Nodejs I strumbeled over this post:

Is it possible to change a Proxy's target?

I for myself have an urge need for beeing able for switching objects without changing and unknown number of (cross-) references.

I saw to possible ways for doing this:

  • Hardcopy and fiddle around on 'running' objects by replaching its attributes and methods on the fly. In fact this sounds a bit too dangerous for productive usage
  • Or by using the smooth ES6 Proxy class. That simply lacks of one thing: target switch.

First I was wondering why the ES6 Guys had not included the posibility for changing an Proxys target in the first place. But after doing it myself I feel like having a clue why.

class Mirror {
  constructor(target) {
    this.ref = target;
  }

  get(target, name, receiver) {
    return this.ref[name];
  }

  set(target, name, value, receiver) {
    if(name=='__target')
      return this.ref = value;

    return this.ref[name] = value;
  }
};

function MetaProxy(target) {
    return new Proxy(target, new Mirror(target));
}

Well. That was Easy. Now have an test app for testing. I decided to use an smal class called "Point". You can use basically everything you want.

let p = MetaProxy(new Point(1,1));
let p2 = new Point(10,10);

let a = p;
console.log(p + " " + p.x + '/' + p.y);

p.__target = p2;

let b = p;
console.log(p + " " + p.x + '/' + p.y);

console.log(a);
console.log(b);
console.log(a + " " + a.x + '/' + a.y);
console.log(b + " " + b.x + '/' + b.y);

What should possibly go wrong? Apparently alot! Have a look to the output:

(1, 1) 1/1
(10, 10) 10/10
Point { x: 1, y: 1 }
Point { x: 1, y: 1 }
(10, 10) 10/10
(10, 10) 10/10

Yeah. Sometime it works, and sometimes not. It seems to being more than just a simple issue. I think it might be caused by the V8 itself. His optimizations keeps the old reference and skips the Proxy class.

But well. What to do to solve it? Is it an Bug? Im Not sure.





Aucun commentaire:

Enregistrer un commentaire