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

Wrapped calls within a runSync block do not resolve #6

Open
tel opened this issue Jun 12, 2015 · 4 comments
Open

Wrapped calls within a runSync block do not resolve #6

tel opened this issue Jun 12, 2015 · 4 comments

Comments

@tel
Copy link

tel commented Jun 12, 2015

If I have a function func being called in a runSync block atop an item which is only retrieved asynchronously

Async.runSync((done) => {
  asyncProcess((err, thing) => done(err, func(thing)));
});

then it will succeed so long as func is itself a direct, synchronous call. In actuality, func may be a function derived from a call to Async.wrap

function func(thing) {
  return Async.wrap(thing.goGetAnotherThing)();
}

However, in this circumstance it appears that the wrapped function does not resolve properly as in my (convoluted, unsharable as of yet) testing the original call will resolve as null.

It's very possible that there's merely a bug in my code somewhere, but this appears to be some kind of synchronicity/fibers/futures interaction difficulty. Any suggestions?

@arunoda
Copy link
Member

arunoda commented Jun 12, 2015

That's possible.

I didn't check, this is just an idea looking at this code.

Your func functions is called inside a run wrapped environment and does not
have fiber.

That may be the case. But I am not exactly sure.

BTW: you can call func synchronously once you got the data.

On 2015 ජූනි 12, සිකු at පෙ.ව. 5.54 Joseph Abrahamson <
[email protected]> wrote:

If I have a function func being called in a runSync block atop an item
which is only retrieved asynchronously

Async.runSync((done) => {
asyncProcess((err, thing) => done(err, func(thing)));
});

then it will succeed so long as func is itself a direct, synchronous
call. In actuality, func may be a function derived from a call to
Async.wrap

function func(thing) {
return Async.wrap(thing.goGetAnotherThing)();
}

However, in this circumstance it appears that the wrapped function does
not resolve properly as in my (convoluted, unsharable as of yet) testing
the original call will resolve as null.

It's very possible that there's merely a bug in my code somewhere, but
this appears to be some kind of synchronicity/fibers/futures interaction
difficulty. Any suggestions?


Reply to this email directly or view it on GitHub
#6.

@tel
Copy link
Author

tel commented Jun 12, 2015

I suppose it is, yes. The (external, non-Fibered) function asyncProcess is the one who actually calls the function which calls func. So that makes sense as to why func doesn't run properly.

The reason I don't merely return the data and then call func on it is that asyncProcess actually uses its callback repeatedly. The example I gave elided that, so let me expand it.

Assume we have a function mapConcurrently which takes two arguments. The second is a standard callback taking (err, result). The first is a function of two arguments, item and callback. The job of this function is to transform the item and pass either it or an error to callback. The operation of mapConcurrently is that it provides access to a set of items allowing the user to transform them all.

In standard Node.js parlance we might write

items.mapConcurrently(
  (item, cb) => { cb(null, item+1) },
  (err, result) => { console.log(result) }
);

Now, I'd like to synchronize this function. The current way I'm doing it is as follows

function mapConcurrentlySync(func) {
  return Async.runSync((done) => {
    items.mapConcurrently(
      (item, cb) => { cb(null, func(item)) },
      done
    );
  });
}

And now, yeah, it becomes much more clear that func will be called in a non-fibered environment. I also cannot just return the data because then the concurrent mapping property is lost. I may have to do more dramatic surgery to make this synchronous.

@arunoda
Copy link
Member

arunoda commented Jun 12, 2015

I understand, concurrent mapping is something does not work with just
fibers.
May be write it in full node and move the result back to Meteor.

Don't know. May be this is just seems like an idea for new project :)

On Fri, Jun 12, 2015 at 9:32 AM Joseph Abrahamson [email protected]
wrote:

I suppose it is, yes. The (external, non-Fibered) function asyncProcess
is the one who actually calls the function which calls func. So that
makes sense as to why func doesn't run properly.

The reason I don't merely return the data and then call func on it is
that asyncProcess actually uses its callback repeatedly. The example I
gave elided that, so let me expand it.

Assume we have a function mapConcurrently which takes two arguments. The
second is a standard callback taking (err, result). The first is a
function of two arguments, item and callback. The job of this function is
to transform the item and pass either it or an error to callback. The
operation of mapConcurrently is that it provides access to a set of items
allowing the user to transform them all.

In standard Node.js parlance we might write

items.mapConcurrently(
(item, cb) => { cb(null, item+1) },
(err, result) => { console.log(result) }
);

Now, I'd like to synchronize this function. The current way I'm doing it
is as follows

function mapConcurrentlySync(func) {
return Async.runSync((done) => {
items.mapConcurrently(
(item, cb) => { cb(null, func(item)) },
done
);
});
}

And now, yeah, it becomes much more clear that func will be called in a
non-fibered environment. I also cannot just return the data because then
the concurrent mapping property is lost. I may have to do more dramatic
surgery to make this synchronous.


Reply to this email directly or view it on GitHub
#6 (comment)
.

@tel
Copy link
Author

tel commented Jun 12, 2015

There really ought to be a way, but I think it would require being more specific about the introduction of Futures. I'll look into it another time. Thanks!

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

No branches or pull requests

2 participants