Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support returning engines to pool via scope/using #7

Closed
binki opened this issue May 19, 2015 · 2 comments
Closed

Support returning engines to pool via scope/using #7

binki opened this issue May 19, 2015 · 2 comments

Comments

@binki
Copy link

binki commented May 19, 2015

I’m looking at the pattern suggested in the README:

var engine = pool.GetEngine();
var message = engine.CallFunction<string>("sayHello", "Daniel");
Console.WriteLine(message); // "Hello Daniel!"

// Always release an engine when you're done with it. This adds the engine back
// into the pool so it can be used again.
pool.ReturnEngineToPool(engine);

I think it would be nicer to be able to do something like:

using (var scopedEngine = pool.GetScopedEngine())
{
    // Access the JavaScriptEngineSwitcher interface either by
    // the Engine property or store it in a local variable for less typing:
    var engine = scopedEngine.Engine;
    var message = engine.CallFunction<string>("sayHello", "Daniel");

    // Let scoping call Dispose() for us and take care
    // of returning the engine to the pool. No more accidents!
}

Though it would be more fragile (if JavaScripEngineSwitcher adds more methods to IJsEngine, we’d break until fixed), it might even be more convenient if the object returned by pool.GetScopedEngine() implemented IJsEngine and proxied everything but Dispose() down to the actual IJsEngine. Then it could be even more sugary:

using (var engine = pool.GetScopedEngine())
{
    var message = engine.CallFunction<string>("sayHello", "Daniel");

    // Let scoping call Dispose() for us and take care
    // of returning the engine to the pool. No more accidents!
}

I have chosen a new function name, IJsPool.GetScopedEngine(), because existing code written against IJsPool.GetEngine() might make assumptions that this change in API would render invalid. Or, perhaps you’re willing to make a breaking change since this library is still a bit younger and using(){} is awesome enough to be worth it? If the scoping wrapper implemented IJsEngine and proxied methods to the wrapped real IJsEngine, the change in API would be transparent to the caller (you could leave ReturnEngineToPool() around and mark it with ObsoleteAttribute to encourage adoption of using(){}).

Thoughts? For now, I’m implementing something like this in my private code (using extension methods), but being able to use using(){} out of the box would make this library feel more complete.

@Daniel15
Copy link
Owner

Yeah, that's a good idea!

My original use case was having one engine per web request so I couldn't use using, as the place I get the engine for the current request is different to the place I dispose the engine, it's not a single code block. Having said that, making Dispose return the engine to the pool would probably actually make it easier to use this library with dependency injection, as IoC containers call Dispose when stuff falls out of scope (eg. for per-request singletons once the request is finished).

I think the issue will be that calling Dispose today will actually dispose the engine itself. I'd need to have an adapter/proxy class that wraps the real engine, keeps track of which pool it belongs to, and overrides Dispose. I already do this for the MSIE engine since it can only be used from the same thread it was created on (JsEngineWithOwnThread), but this change would involve doing it for all engines. That might be fine though.

I have chosen a new function name, IJsPool.GetScopedEngine(), because existing code written against IJsPool.GetEngine() might make assumptions that this change in API would render invalid.

I think it'd be fine to just use GetEngine . This change would only change what Dispose does, and code shouldn't be touching Dispose right now (engines should always be returned to the pool).

Daniel15 added a commit that referenced this issue May 15, 2017
…o call ReturnEngineToPool

To handle this, the engine is wrapped in a class that overrides Dispose and does the right thing.

References #7
References https://github.com/Wyamio/Wyam/pull/452
@Daniel15
Copy link
Owner

Daniel15 commented Jul 1, 2017

Released in 3.0

@Daniel15 Daniel15 closed this as completed Jul 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants