-
Notifications
You must be signed in to change notification settings - Fork 12
fix(y-mongodb.js): Prevent service disruption due to failed data updates #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7387378
c28fb4b
34f09fa
411762d
c089c39
b9df53a
70a916b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "y-mongodb-provider", | ||
"version": "0.2.0", | ||
"name": "y-mongodb-provider-crashsafe", | ||
"version": "0.2.4", | ||
"description": "MongoDB database adapter for Yjs", | ||
"type": "module", | ||
"main": "./dist/y-mongodb.cjs", | ||
|
@@ -23,12 +23,12 @@ | |
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/MaxNoetzold/y-mongodb-provider.git" | ||
"url": "git+https://github.com/lukenc/y-mongodb-provider.git" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nor this |
||
}, | ||
"author": "Max Nötzold <[email protected]>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/MaxNoetzold/y-mongodb-provider/issues" | ||
"url": "https://github.com/lukenc/y-mongodb-provider/issues" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nor that |
||
}, | ||
"dependencies": { | ||
"lib0": "^0.2.94", | ||
|
@@ -54,7 +54,7 @@ | |
"dist/*", | ||
"src/*" | ||
], | ||
"homepage": "https://github.com/MaxNoetzold/y-mongodb-provider#readme", | ||
"homepage": "https://github.com/lukenc/y-mongodb-provider#readme", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
"keywords": [ | ||
"Yjs", | ||
"MongoDB", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ import * as promise from 'lib0/promise'; | |
import { MongoAdapter } from './mongo-adapter.js'; | ||
import * as U from './utils.js'; | ||
|
||
const APPLY_FULL_STATUS = 'applyFull'; | ||
|
||
export class MongodbPersistence { | ||
/** | ||
* Create a y-mongodb persistence instance. | ||
|
@@ -47,13 +49,14 @@ export class MongodbPersistence { | |
this.tr = {}; | ||
|
||
/** | ||
* Execute an transaction on a database. This will ensure that other processes are | ||
* Execute a transaction on a database. This will ensure that other processes are | ||
* currently not writing. | ||
* | ||
* This is a private method and might change in the future. | ||
* | ||
* @template T | ||
* | ||
* @param docName The name of the document | ||
* @param {function(MongoAdapter):Promise<T>} f A transaction that receives the db object | ||
* @return {Promise<T>} | ||
*/ | ||
|
@@ -101,13 +104,40 @@ export class MongodbPersistence { | |
return this._transact(docName, async (db) => { | ||
const updates = await U.getMongoUpdates(db, docName); | ||
const ydoc = new Y.Doc(); | ||
let applyNum = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this variable doesnt say what it does, it needs some kind of renaming |
||
ydoc.transact(() => { | ||
for (let i = 0; i < updates.length; i++) { | ||
Y.applyUpdate(ydoc, updates[i]); | ||
try { | ||
Y.applyUpdate(ydoc, updates[i]); | ||
} catch (e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you catch all errors now and remove the option for error handling at later stages at all. This is probably a bad idea, but I am not super sure if error handling was an option anyways because of the transact wrapper. However, I am even wondering if this makes any sense. If an error is thrown when applying an update, the flush later on wont be happening without your changes, so it doesnt change anything but just adds logging? |
||
console.warn(`Failed to apply update ${i} to document "${docName}".`, e); | ||
break; | ||
} | ||
applyNum += 1; | ||
} | ||
}); | ||
if (updates.length > this.flushSize) { | ||
await U.flushDocument(db, docName, Y.encodeStateAsUpdate(ydoc), Y.encodeStateVector(ydoc)); | ||
// 检查是否所有更新都已应用 | ||
const allUpdatesApplied = applyNum === updates.length; | ||
|
||
// 设置应用状态 | ||
ydoc.getMap(APPLY_FULL_STATUS).set('status', allUpdatesApplied); | ||
|
||
if (allUpdatesApplied) { | ||
// 判断是否需要执行文档刷新 | ||
if (updates.length > this.flushSize) { | ||
// 更新数量超过阈值且全部应用成功,执行文档刷新 | ||
await U.flushDocument( | ||
db, | ||
docName, | ||
Y.encodeStateAsUpdate(ydoc), | ||
Y.encodeStateVector(ydoc), | ||
); | ||
} | ||
} else { | ||
// 未能全部应用成功,记录警告 | ||
console.log( | ||
`Failed to apply all updates to document "${docName}". Applied ${applyNum}/${updates.length} updates.`, | ||
); | ||
} | ||
return ydoc; | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wont do that