question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Concurrency issues with 0.7

See original GitHub issue

I’m observing a strange behavior with concurrent requests. I have read all the issues on that matter and I think I’m using the library (0.7) properly (i.e. not using global i18n.setLocale()).

app.js

var app = express();

// Add helpers to handlebars
app.use(function(req, res, next) {
  handlebars.registerHelper('i18n', function() {
    return i18n.__.apply(req, arguments);
  });
  next();
});

// Configure i18n
i18n.configure({
  objectNotation: true,
  locales: ['en', 'fr'],
  defaultLocale: 'en',
  directory: path.join(__dirname, '/locales/server')
});

app.use(i18n.init);

routes/foo.js

var sendEmail = function(req, res, next) {
  var locale = req.user.preferredLocale; // can be 'fr' or 'en'
  req.setLocale(locale);
  handlebars.render('email.hbs', { firstName: 'John' });
}

views/email.hbs

{{i18n 'common.hello' firstName}}

When I render one email at a time, either in english or french, it works fine. But if I send 2+ emails in a for loop I’m starting to get emails in random languages. It seems that each time I run the loop I get different languages.

To your knowledge, is the configuration above correct? I read the code of setLocale and I don’t see where the locale could leak from a req to another. But how can you explain that the issue only occurs when sending multiple requests in a short amount of time?

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
gzurbachcommented, Feb 17, 2016

Sorry for the noise I just figured out what the issue was. Long story short, the app is sharing a single instance of Handlebars. Therefore its helper was getting overridden each time a request was initiated.

The solution simply consists in using the data.root.locale from the last argument of the helper.

app.use(function(req, res, next) {
  handlebars.registerHelper('i18n', function() {
    var args = Array.prototype.slice.call(arguments);
    var options = args.pop();
    return i18n.__.apply(options.data.root, args);
  });
  next();
});

I had tried this solution a while ago but because emails are rendered outside of a req/res context the locale was not present in data.root. I had to pass it manually. That was one of the most painful debugging I had to do in a while 😃

Thanks for your help!

0reactions
gzurbachcommented, Aug 19, 2016

I use espress-handlebars as well. Here is the relevant code in my app:

In the app.js

expressHandlebars = require('express-handlebars');

var hbs = expressHandlebars.create({
  extname: '.hbs'
});

hbs.handlebars.registerHelper('i18n', function() {
  var args = Array.prototype.slice.call(arguments);
  var options = args.pop();
  return i18n.__.apply(options.data.root, args);
});

Then when I send an email, I have to pass the desired locale as a “context”:

sendEmail({
  from: 'foo@bar.com',
  to: 'bar@foo.com',
  subject
}, {
  message: message,
  locale
});

In the handlebars view I do not have to pass the locale when using the i18n helper:

{{i18n 'myKey' someOtionalParam}}

This is the only way for options.data.root to contain the right locale. Let me know if you need further details.

Read more comments on GitHub >

github_iconTop Results From Across the Web

0.7.7 – 0.7.13 Duration Measure, Basic Mode for Concurrency ...
Concurrency rules determine how many sets, targets, and phases are exercised at a given time and in what order they are presented. Basic...
Read more >
Concurrency · Issue #564 · carrierwaveuploader/carrierwave
So I'm trying Rackspace, but it's taking hours to upload just 10.000 small 1-72kb files without threads, while it took only 1-5 minutes...
Read more >
PI23831: URELEASE CONCURRENCY ISSUES WITH ... - IBM
If multiple concurrent REST requests are sent with the same user credentials, only one of the concurrent requests will succeed.
Read more >
Configuring provisioned concurrency - AWS Lambda
In Lambda, concurrency is the number of requests your function can handle at the same time. There are two types of concurrency controls...
Read more >
concurrent-extra: Extra concurrency primitives - Hackage
The concurrent-extra package offers among other things the following selection of synchronisation primitives:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found