title: Node/Express: concurrency issues when using session to store state
body: <p>So, I've searched quite a bit for this and found several somewhat similar questions, none of them really addressing the problem though so I thought this deserved a question of its own.</p>
  
  <p>I have an express application with a bunch of routes that modify the session to keep state. Thing is, if there are multiple parallel requests, from time to time the session will be overwritten due to race conditions between requests.</p>
  
  <p>So typically</p>
  
  <pre><code>...
  app.use(express.static('/public'));
  app.use(session(...));
  app.route('methodA').get(function(req, res, next) {
      doSomethingSlow().then(function() {
          req.session.a = 'foo';
          res.send(...);
      }
  });
  app.route('methodB').get(function(req, res, next) {
      doSomethingElseSlow().then(function() {
          req.session.b = 'bar';
          res.send(...);
      }
  });
  </code></pre>
  
  <p>Basically the problem is straightforward and is e.g. described  in <a href="https://stackoverflow.com/a/8523574">this</a> answer. Express stores the session in res.end(), but while a methodA request is being handled, a methodB request could have modified the session in the meantime so that when methodA stores the session it will overwrite any changes made by methodB. So even though node is single-threaded and all requests are served by the same thread we can end up with concurrency issues as soon as any method is doing something asynchronous thereby letting other requests be handled simultaneously.</p>
  
  <p>However, I am struggling to decide how I should proceed to solve this problem. All answers I have found only list ways of <em>minimizing the probability</em> of this happening, e.g. by making sure static content does not store the session by registering the serve-static MW before the session MW. But this only helps to some extent; if there are in fact API methods that are supposed to be called in parallel some real concurrency approach to session updates is needed (IMO, when it comes to concurrency issues, every "solution" that strives to minimize the probability of problems occuring rather than addressing the actual problem is bound to go wrong).</p>
  
  <p>Basically these are the alternatives I am exploring so far:</p>
  
  <ol>
  <li><p><strong>Prevent parallel requests within the same session completely by modifying my client to make sure it calls all API methods serially.</strong></p>
  
  <p>This may be possible but will have quite some impact on my architecture and may impact performance. It also avoids the problem rather than solves it and if I make something wrong in my client or the API is used by another client I might still run into this randomly, so it doesn't feel very robust.</p></li>
  <li><p><strong>Make sure each session write is preceded by a session reload and make the entire reload-modify-write operation atomic.</strong></p>
  
  <p>I am not sure how to achieve this. Even if I modify res.end() to reload the session <em>just</em> before modifying and storing it, because reading and writing the session is async I/O it seems possible that this could happen:</p>
  
  <ul>
  <li>request A reloads the session</li>
  <li>request A modifies session.A = 'foo'</li>
  <li>request B reloads the session (and will not see session.A)</li>
  <li>request A stores the session</li>
  <li>request B modifies session.B = 'bar'</li>
  <li>request B stores the session, overwriting previous store so that session.A is missing</li>
  </ul></li>
  </ol>
  
  <p>So in essence I would need to make each reload-modify-store atomic, which basically means blocking the thread? Feels wrong, and I have no idea how to do it.</p>
  
  <ol start="3">
  <li><p><strong>Stop using the session in this way altogether and pass necessary state as params to each request or by some other means.</strong></p>
  
  <p>This also avoids the problem rather than addressing it. It would also have huge impact on my project. But sure, it might be the best way.</p></li>
  <li><p><strong>???</strong></p></li>
  </ol>
  
  <p>Anyone got any ideas how to address this in a robust way?
  Thanks!</p>