【问题标题】:Seat booking logic for meteor react application流星反应应用程序的座位预订逻辑
【发布时间】:2018-09-29 16:11:38
【问题描述】:

我正在开发一个座位有限的流星预订应用程序。我的应用程序可以被多个用户并行使用,因此两个用户可能会尝试预订同一个座位。但根据业务逻辑,座位永远不会被超额预订。在 Java 中,我可以使用同步块来限制并行预订。我在流星/反应方面没有太多经验,所以不确定实现这一目标的正确方法是什么。

我目前的想法是使用反应性布尔值来创建锁,因此如果应用程序收到两个预订请求,那么它会同步处理它们并使第二个预订请求失败。由于座位将在第一次请求中分配。但我担心我是否会陷入僵局。因此,我正在寻求您的意见/帮助,以便以适当的方式实现这一点。

感谢您的建议!

【问题讨论】:

  • 我假设正在谈论 node.js,因为看起来 meteor 正在使用节点。节点是单线程的,因此您无法获得真正的死锁。但是你可以做的是创建一个全局承诺,每次你启动一个进程时,你将这个承诺设置为当前的,然后你可以awaitthen这个承诺来确保它不会在最后一个。

标签: javascript mongodb reactjs meteor


【解决方案1】:

我在这里假设你的后端是 node.js,被视为你在使用流星,你已经在使用 NPM,所以使用 Node 的后端是有意义的。

在这种情况下,假设您使用 Express 或 KOA 来处理您的请求,您可以简单地使用 Promise 链接您的任务,这将强制任务线性执行。

下面是一个简单的工作示例,如果您运行 sn-p,您会注意到我每 700 毫秒添加一次任务,但任务只能在 1000 毫秒内完成,但正如您所见,没有重叠并且任务完成按顺序排列。

const delay = (ms) => new Promise((r) => setTimeout(r, ms));

let lastTask = Promise.resolve();

async function addTask(txt) {
  const ptask = lastTask;
  lastTask = (async () => {
    await ptask;
    console.log(`starting task ${txt}`);
    await delay(1000);
    console.log(`done task ${txt}`);
  })();
}

async function test() {
  for (let l = 0; l < 5; l += 1) {
    setTimeout(() => {
      console.log(`adding task ${l}`);
      addTask(l);
    }, l * 700);
  }
}

test();

【讨论】:

    【解决方案2】:

    如果您在 Meteor 中使用 pub/sub,那么工作就完成了。您的预订是反应式的,先到先得。只要您的连接处于打开状态,当您编写第一个预订时,座位就会被占用。

    例如(逻辑写作)

    1 在所需范围内发布您的预订。

    2.在同一范围内订阅客户端。

    3.如果文档bookedOn $exists(预订日期)使“不可预订”/不可点击,则让用户体验显示必要的颜色/体验。

    当一个人预订它时,所有在平台上在线并查看该组件的用户都会得到更新。

    如果您不使用 pubs/subs 但很常见,这将是一个“问题”……您在 Meteor 上,您应该使用 Meteor 的本机反应性。您的布尔值是 Boolean(bookedOn) 或刚刚bookedOn。

    【讨论】:

      【解决方案3】:

      我认为meteor的做法是调用meteor方法,比用户占位。 在这个方法中检查这个座位是否已经被占用。 更多信息在这里: https://forums.meteor.com/t/if-multiple-users-are-trying-to-access-one-method-of-meteor-methods-how-to-make-method-as-synchronous-to-use-one-user-only-at-a-time/24969/8

      但是来自不同客户端的方法在服务器上同时运行。 你必须使用信号量之类的东西。最简单的方法是在 mongo 中写一个锁,并检查该席位是否不存在该锁。之后锁可以被 mongo 销毁,TTL https://docs.mongodb.com/manual/tutorial/expire-data/

      您可以在此处阅读有关方法的更多信息https://guide.meteor.com/methods.html

      总结一下,伪代码是这样的:

      accuireLock(userId, seatId); // 将读取锁,如果它是空闲的,则写入它,然后再次读取以防万一。任何失败都应该抛出错误

      takeSeat(userId, seatId);

      【讨论】:

        猜你喜欢
        • 2013-06-05
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-17
        相关资源
        最近更新 更多