Node.js Шаблон программирования для получения контекста выполнения

Я пишу веб-приложение в node.js. Теперь каждая обработка на сервере всегда находится в контексте сеанса, который либо извлекается, либо создается на самом первом этапе, когда запрос попадает на сервер. После этого выполнение протекает через несколько модулей и обратные вызовы внутри них. То, с чем я борюсь, заключается в создании шаблона программирования, так что в любой момент кода объект сеанса доступен без программирования, требующего, чтобы он передавал его в качестве аргумента в каждом вызове функции.

Если бы весь код был в одном файле, я мог бы иметь закрытие, но если есть вызовы функций другим модулям в других файлах, как я программирую, чтобы объект сеанса был доступен в вызываемой функции, не передавая ее как Аргумент. Я чувствую, что должна быть какая-то связь между двумя функциями в двух файлах, но как организовать, где я застреваю.

В общем, я бы хотел сказать, что всегда есть контекст выполнения, который может быть сеансом или сетевым запросом, обработка которого распространяется на несколько файлов, а объект контекста выполнения должен быть доступен во всех точках. На самом деле может быть несколько случаев использования, таких как наличие одного объекта журнала для каждого сетевого запроса или одного объекта журнала за сеанс. И сантехника, необходимая для выполнения этой работы, должна быть установлена ​​сбоку без использования прикладного программатора. Он просто знает, что контекст исполнения доступен во всех местах.

Я думаю, что это должна быть довольно распространенная проблема, с которой сталкиваются все, поэтому, пожалуйста, дайте мне несколько идей.

Ниже приведена проблема

MainServer.js


  app = require('express').createServer();
  app_module1 = require('AppModule1');
  var session = get_session();
  app.get('/my/page', app_module1.func1);

AppModule1.js

  app_module2 = require('AppModule2');
  exports.func1 = function(req,res){

     //  I want to know which the session context this code is running for

     app_module2.func2(req,res);

   }

AppModule2.js

   exports.func2 = function(req,res){

    // I want to know where the session context in which this code is running

    }

Ответы

Ответ 1

Вы можете достичь этого, используя Domains - новую функцию node 0.8. Идея состоит в том, чтобы запускать каждый запрос в своем собственном домене, предоставляя пространство для данных для запроса. Вы можете перейти в текущий домен запроса, не передавая его через process.domain.

Вот пример того, как настроить его для работы с выражением: Как использовать домены Node.js 0.8.x с экспресс?

Обратите внимание, что домены в целом несколько экспериментальные и process.domain, в частности, недокументирован (хотя, по-видимому, не уходит в 0.8, и есть некоторые дискуссии о том, чтобы сделать его постоянным). Я предлагаю следовать их рекомендации и добавлять свойство, специфичное для приложения, для process.domain.data.

https://github.com/joyent/node/issues/3733

https://groups.google.com/d/msg/nodejs-dev/gBpJeQr0fWM/-y7fzzRMYBcJ

Ответ 2

Поскольку вы используете Express, вы можете подключить сеанс к каждому запросу. Реализация следующая:

var express = require('express');
var app = express.createServer();
app.configure('development', function() {
  app.use(express.cookieParser());
  app.use(express.session({secret: 'foo', key: 'express.sid'}));
});

Затем по каждому запросу вы можете получить доступ к сеансу следующим образом:

app.get('/your/path', function(req, res) {
  console.log(req.session);
});

Я предполагаю, что вы хотите иметь какой-то уникальный идентификатор для каждого сеанса, чтобы вы могли отслеживать его контекст. SessionID можно найти в cookie 'express.sid', который мы устанавливаем для каждого сеанса.

app.get('/your/path', function(req, res) {
  console.log(req.cookies['express.sid']);
});

В принципе, вам не нужно ничего делать, кроме добавления парсера cookie и включения сеансов для вашего экспресс-приложения, а затем, когда вы передаете запрос на эти функции, вы можете распознать идентификатор сеанса. Вы ДОЛЖНЫ передать запрос, хотя вы не можете создать систему, в которой он просто знает сеанс, потому что вы пишете сервер, а сеанс доступен по запросу.

Ответ 3

То, что выражается, и распространенная практика для создания http-стека на node.js, использует промежуточное программное обеспечение http для "повышения" или добавления функциональности для объектов запроса и ответа, входящих в обратный вызов с вашего сервера. Это очень просто и прямолинейно.

module.exports = function(req, res, next) {
    req.session = require('my-session-lib');
    next(); 
};

req и res автоматически передаются в ваш обработчик, и от них вам нужно будет держать их доступными для соответствующих слоев вашей архитектуры. В вашем примере это доступно следующим образом:

AppModule2.js

exports.func2 = function(req,res){

    // I want to know where the session context in which this code is running
    req.session; // <== right here

}

Ответ 4

Nodetime - это инструмент профилирования, который делает внутренне то, что вы пытаетесь сделать. Он предоставляет функцию, которая кодирует ваш код таким образом, что вызовы, вызванные конкретным HTTP-запросом, связаны с этим запросом. Например, он понимает, сколько времени было потрачено на запрос в Mongo, Redis или MySQL. Посмотрите видео на сайте, чтобы увидеть, что я имею в виду http://vimeo.com/39524802.

Библиотека добавляет пробники к различным модулям. Тем не менее, я не смог понять, как именно между ними передается контекст (url). Надеюсь, кто-то может понять это и опубликовать объяснение.

EDIT: Извините, я думаю, что это была красная селедка. Nodetime использует трассировку стека для связывания вызовов друг с другом. Результаты, которые он представляет, представляют собой агрегаты между потенциально многими вызовами одного URL-адреса, поэтому это не решение проблемы OP.