英文:
How to share a specific utils function between different files in nodeJS to keep track of 3 MongoDB collection names
问题
Sure, here's the translated content you requested:
getLetter.js 文件
// 每次返回包含三个不同字母值的对象:
const XYZ = { I: 'X', II: 'Y', III: 'Z' };
const YZX = { I: 'Y', II: 'Z', III: 'X' };
const ZXY = { I: 'Z', II: 'X', III: 'Y' };
let nr = 1;
function getLetter() {
let obj;
if (nr == 1) {
obj = XYZ;
nr++;
return obj;
} else if (nr == 2) {
obj = YZX;
nr++;
return obj;
} else if (nr == 3) {
obj = ZXY;
nr = 1;
return obj;
}
}
server.js 文件
function intervalFunction() {
insertCollection();
consumeCollection();
dropCollection();
}
if (isInserted && isDropped) {
setInterval(intervalFunction, 5000);
}
insertCollection.js 插入新集合的伪代码
let newCollectionName = `collection_${getLetter().III}`;
if (isNewCollectionNameInserted) isInserted = true;
consumeCollection.js 提供实际集合(经过聚合)的API端点的伪代码
let actualCollection = `collection_${getLetter().II}`;
dropCollection.js 从MongoDB中删除旧集合的伪代码
let oldCollection = `collection_${getLetter().I}`;
if (isOldCollectionDropped) isDropped = true;
I've provided the translated code snippets as requested.
英文:
I have to keep track of three collection names for three MongoDB collection.
One to insert a json data from an API. The second to consume the data in my own API (this is necessary because I have to avoid the calls restrictions to the API provider). And the third to drop the "old" collection. And this will be repeating every 5 seconds endless. If the following code stay together in one file is no problem, but I have to separate them in 3 different files/modules. My question is what approach is the right one to make it work in NodeJS
and to keep the names consistently? At this point, when I run the code the getLetter()
it just start over and return the same object every iteration. Here the most important part of code as pseudo code. If you have some experience please help. Thank you!
getLetter.js utils file
// return each time the next object with three different letters as value:
const XYZ = { I: 'X', II: 'Y', III: 'Z' };
const YZX = { I: 'Y', II: 'Z', III: 'X' };
const ZXY = { I: 'Z', II: 'X', III: 'Y' };
let nr = 1;
function getLetter() {
let obj;
if (nr == 1) {
obj = XYZ;
nr++;
return obj;
} else if (nr == 2) {
obj = YZX;
nr++;
return obj;
} else if (nr == 3) {
obj = ZXY;
nr = 1;
return obj;
}
}
server.js file
function intervalFunction() {
insertCollection();
consumeCollection();
dropCollection();
}
if (isInserted && isDropped) {
setInterval(intervalFunction, 5000);
}
insertCollection.js Pseudo code to insert the "new" collection in MongoDB
let newCollectionName = `collection_${getLetter().III}`;
if (isNewCollectionNameInserted) isInserted = true;
consumeCollection.js Pseudo code to deliver the "actual" collection (after aggregation) in an API endpoint
let actualCollection = `collection_${getLetter().II}`;
dropCollection.js Pseudo code to drop the "old" collection from MongoDB
let oldCollection = `collection_${getLetter().I}`;
if (isOldCollectionDropped) isDropped = true;
答案1
得分: 1
以下是您要翻译的内容:
不确定我是否理解问题,但我会尽力帮助:
而不是使用3个模块(插入、消耗、删除),我会使用2个:
- 更新集合
- 消耗集合
getLetter.js 实用程序文件
let index = 0;
const letters = ['X', 'Y', 'Z'];
function getLetter() {
return letters[index];
}
function updateIndex() {
index = (index + 1) % 3;
}
console.log(getLetter()); // X
updateIndex();
console.log(getLetter()); // Y
然后,您可以这样做:
server.js 文件
function intervalFunction() {
updateCollection();
consumeCollection();
}
setInterval(intervalFunction, 5000);
updateCollection.js 文件
updateCollection() {
updateIndex();
}
consumeCollection.js 文件
let actualCollection = `collection_${getLetter()}`;
这样,您就不必每次都删除集合。
希望这是您所寻找的。
英文:
Not sure I understand the problem but I will try to help:
instead of 3 modules (insert, consume, drop) I would use 2:
- update collection
- consume collection
getLetter.js utils file
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let index = 0;
const letters = ['X', 'Y', 'Z'];
function getLetter() {
return letters[index];
}
function updateIndex() {
index = (index + 1) % 3;
}
console.log(getLetter()); // X
updateIndex();
console.log(getLetter()); // Y
<!-- end snippet -->
Then you can do something like that:
server.js file
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function intervalFunction() {
updateCollection();
consumeCollection();
}
setInterval(intervalFunction, 5000);
<!-- end snippet -->
updateCollection.js file
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
updateCollection() {
updateIndex();
}
<!-- end snippet -->
consumeCollection.js file
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let actualCollection = `collection_${getLetter()}`;
<!-- end snippet -->
This way you won't have to delete the collection every time.
Hope it is what you looked for.
答案2
得分: -1
在我的看法中,你不应该在你的Node.js代码中存储'状态'。将它推迟到专为此目的构建的服务中。
对于你的例子,一种方法(众多解决方案之一)是使用Redis存储锁,以及这些配置的键/值对。
结合使用redis
和redis-lock
//insertCollection ....
const client = require("redis").createClient(),
lock = require("redis-lock")(client);
async function insertTheNewCollection(collectionName) {
const value = await client.get(collectionName);
if (!value) {
// 将新集合插入到MongoDB
// 将键添加到Redis。
await client.set(collectionName, 'i-exist');
}
}
async function doTheInsert(collectionName) {
await client.connect(); // 需要配置连接
console.log("请求锁");
let done;
try {
done = await lock(collectionName); // 在集合名称上加锁。 (你也可以在超时时间内获取锁)
console.log("锁已获取");
await insertTheNewCollection() // 一些异步任务
console.log("现在释放锁");
} finally {
if (done) { // 即使抛出异常,也要释放锁。
await done()
}
}
}
其他方法的模式相同... 获取锁,进行一些工作,关闭锁。
这样,你的'server.js'实际上可以将方法放在不同的API端点中... 你可以分别或同时调用每个端点。现在你可以在多台服务器上运行它,而Redis将成为共享的'状态'存储的地方。
这不是唯一的答案,但是一个可能的解决方案。
英文:
IMHO, you should not be storing 'state' in your nodejs code. Push that off to a service built for that.
For your example, one approach (among many solutions) would be to use Redis to store a lock, and key/value of those configs..
combo of using redis
and redis-lock
//insertCollection ....
const client = require("redis").createClient(),
lock = require("redis-lock")(client);
async insertTheNewColleciton(collectionName) {
const value = await client.get(collectionName);
if(!value) {
// insert new collection into mongo
//add key to redis.
await client.set(collectionName, 'i-exist');
}
}
async doTheInsert(collectionName){
await client.connect(); //will need to configure the connectivity
console.log("Asking for lock");
let done;
try {
done = await lock(collectionName); //lock on the collection name. (you can also acquire a lock, with a time out)
console.log("Lock acquired");
await insertTheNewColleciton() // Some async task
console.log("Releasing lock now");
finally{
if (done) { // even if an exception is thrown, or not.. release lock.
await done()
}
}
}
Same Pattern for the Other Method... acquire the lock, do some work, close the lock
This way.. your 'server.js' can actually put the methods in different api endpoints... and you call call each one separately or together. And now you can run this on multiple servers, and Redis will be to common 'state' store.
Not the only answer, but one possible solution.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论