Session 是否可以在vibe.d中全局存储当前会话信息?(德朗)

Session 是否可以在vibe.d中全局存储当前会话信息?(德朗),session,d,vibed,Session,D,Vibed,该站点的示例如下: import vibe.d; void login(HTTPServerRequest req, HTTPServerResponse res) { enforceHTTP("username" in req.form && "password" in req.form, HTTPStatus.badRequest, "Missing username/password field."); // todo: verify u

该站点的示例如下:

import vibe.d;

void login(HTTPServerRequest req, HTTPServerResponse res)
{
    enforceHTTP("username" in req.form && "password" in req.form,
        HTTPStatus.badRequest, "Missing username/password field.");

    // todo: verify user/password here

    auto session = res.startSession();
    session["username"] = req.form["username"];
    session["password"] = req.form["password"];
    res.redirect("/home");
}

void logout(HTTPServerRequest req, HTTPServerResponse res)
{
    res.terminateSession();
    res.redirect("/");
}

void checkLogin(HTTPServerRequest req, HTTPServerResponse res)
{
    // force a redirect to / for unauthenticated users
    if( req.session is null )
        res.redirect("/");
}

shared static this()
{
    auto router = new URLRouter;
    router.get("/", staticTemplate!"index.dl");
    router.post("/login", &login);
    router.post("/logout", &logout);
    // restrict all following routes to authenticated users:
    router.any("*", &checkLogin);
    router.get("/home", staticTemplate!"home.dl");

    auto settings = new HTTPServerSettings;
    settings.sessionStore = new MemorySessionStore;
    // ...
}

但假设我不想在整个程序中将ServerResponse传递到每个函数中。例如,如果res.session正在存储当前用户的id,该怎么办。这是经常使用的,所以我不希望它通过每个函数传递。如何全局存储此会话信息?假设有多个用户在使用该站点。

这是可能的,尽管有点不鼓励

解决方案

您不能简单地全局存储它,因为没有“全局”会话——它总是特定于请求上下文。由于多个光纤共享同一个执行线程,即使在默认情况下在D中使用全局线程本地也没有帮助

对于这样的任务,vibe.d提供了一个模板,允许您完全按照自己的意愿执行。我没有尝试过,但希望
TaskLocal!会话会话
至“仅工作”

请注意文档中的这两个警告:

但是,请注意,每个TaskLocal变量都会增加使用任务本地存储的任何任务的内存占用。访问TaskLocal变量的开销也比线程本地变量的开销要高,但通常仍然是O(1)

FiberLocal实例必须声明为静态/全局线程局部变量。将它们定义为临时/堆栈变量将导致崩溃或数据损坏

反对意见


然而,根据我的经验,尽管打字有点不便,但还是最好明确地传递所有这些上下文。不鼓励使用globals的原因是——随着程序规模的增长,跟踪模块之间的依赖关系和测试此类代码不可避免地变得困难。现在陷入便利的诱惑,以后可能会引起很多头痛。为了尽量减少额外的键入并简化代码维护,我建议改为定义
struct Context{…}
,它将包含请求/会话指针,并将定期传递。。。也许我们需要振动标签:)我知道!我试着回答其他一些问题,只是为了获得所需的声誉。不是一个大的回答者,所以如果你想这样做,我会很感激:)我会尝试添加它,尽管我认为我的代表也不够高。。。