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

Is there a blocking middleware implemented? #8

Open
gabzim opened this issue Mar 10, 2017 · 4 comments
Open

Is there a blocking middleware implemented? #8

gabzim opened this issue Mar 10, 2017 · 4 comments

Comments

@gabzim
Copy link

gabzim commented Mar 10, 2017

Botkit has middleware that allows you to call next() when you're done, allowing you to block the execution of future handlers until an async task is done. I need this but once the apiai request has completed, so I can look at the resp.result obj. Is there any such functionality available?

I need something like:

apiai
    .middleware(function(bot, resp, message, next) {
        // do async task
        next()
    })
@xVir
Copy link
Contributor

xVir commented Mar 15, 2017

Hi @arg20
Did you mean that you want to do some actions after apiai.process(message, bot);

controller.hears('.*', ['direct_message', 'direct_mention', 'mention'], function (bot, message) {
    apiai.process(message, bot);
});

something like

controller.hears('.*', ['direct_message', 'direct_mention', 'mention'], function (bot, message) {
    apiai.process(message, bot, function() {
       // make some actions...
   });
});

What about returning a Promise from apiai.process(message, bot);?
It will looks like:

controller.hears('.*', ['direct_message', 'direct_mention', 'mention'], function (bot, message) {
    apiai.process(message, bot)
      .then(() => {
         // make some actions...
      });
});

What do you think?

Thanks!

@gabzim
Copy link
Author

gabzim commented Mar 16, 2017

@xVir I meant more like I need to load something from the database. So after apiai.process finishes I need to load something from a database asynchronously but I don't want the apiai.action handlers to execute.

For instance, botkit has middleware that works like this:

controller.middleware.heard.use(async(bot, message, next) => {
  // do async stuff and call next when you are done. The handlers for "hears" won't execute until next() is called
  next()
});

Basically I don't want all the .action() functions to execute until I do something first.

To be more concrete. Imagine this example:

apiai.all(function(message, resp, bot) {
  let environment = resp.result.parameters.environment;
  // Go to Db to fetch environment data.
  
  message.ctx = environmentDataFromDb
});

apiai.action('create.environment', function(message, resp, bot) {
  // do not execute until above function finishes, so I can access message.ctx
})

@xVir
Copy link
Contributor

xVir commented Mar 19, 2017

@arg20
Ok, thanks!

So, do you want to add next() function only to apiai.all or to other functions too?

@xVir
Copy link
Contributor

xVir commented Mar 21, 2017

Hi @arg20
It seems to make it work we have to change this part of code:

worker.allCallback.forEach((callback) => {
    callback(message, response, bot);
});

in way like this (using async lib):

async.eachSeries(worker.allCallback, (item, next) => {
    item(message, response, bot, next);    
},
(err) => {
  if (!err) {
    // continue processing..,
  } else {
    // error...
  }
});

But it will be a problem for those, who will update the lib and will not update sources with the next function call. In other words it will break backward compatibility.

So, any thoughts how to get around this?
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