laverdet/node-fibers

Can you use generators with Fibers?

tcf909 opened this issue · 5 comments

@laverdet Any issues with using Fibers with generators and yield that you know of? I know with await there is an issue getting back into a Fiber after awaiting. Anything similar you've run across with generators and yield?

I've tested a bunch of scenarios and everything seems fine, but I have a big implementation to do based on generators and wanted to double check with you before I get too far down the path.

Thanks

I would imagine yield would behave identically to await in this case.

Early testing showed otherwise...which is why I was confused.

I'll post some working examples, but basically upon returning from a yield a Fiber was still available via Fiber.current

It depends on if the original stack has unwound. await will always run on a clean stack but yield might not.

It seems to maintain the original stack -- very interesting. Wonder if there is risk of this breaking in the future. Thoughts?

Test code:

const Sync = require('@digitalspaces/syncho');
Sync(() => {
	function* test(v){
		while(true){
			Sync.wait(cb => setTimeout(cb, 100));
			yield v;
			Sync.wait(cb => setTimeout(cb, 100));
			if( ! require('fibers').current )
				throw new Error();
			console.log(new Error());
/* Output--------------->
  Error
    at test (/Users/tc.ferguson/Sync/Workspace/MyDigitalSpaces/benchmarks/test2.js:26:16)
    at test.next (<anonymous>)
    at /Users/tc.ferguson/Sync/Workspace/MyDigitalSpaces/benchmarks/test2.js:33:13
*/
		}
	}
	for( const v of test()){
		console;
	}
});

I recommend trying without fibers to get a better sense of how generators work.

function* gen() {
	for (;;) {
		console.trace();
		yield;
	}
}

const foo = gen();
foo.next();
process.nextTick(() => foo.next());

Logs:

Trace
    at gen (/Users/marcel/a.js:3:11)
    at gen.next (<anonymous>)
    at Object.<anonymous> (/Users/marcel/a.js:9:5)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
    at internal/main/run_main_module.js:17:11
Trace
    at gen (/Users/marcel/a.js:3:11)
    at gen.next (<anonymous>)
    at /Users/marcel/a.js:10:28
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

If you unwind from a fiber you won't be in a fiber anymore.