Skip to content
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

Add mount option { autoPersist: true } to IDBFS mount. #21938

Merged
merged 8 commits into from
May 23, 2024

Conversation

juj
Copy link
Collaborator

@juj juj commented May 14, 2024

Add new setting -sIDBFS_AUTO_PERSIST which changes the semantics of an IndedexDB mount to automatically persist the VFS to IndexedDB after closing any file that has been written to. This enables users to avoid needing to call FS.syncfs() or fsync() to persist files to the filesystem.

@curiousdannii
Copy link
Contributor

Great idea! I was just adding this to my project (overwriting the default library function), but your way should be much more reliable.

    // Sync IDBFS after saving a savefile
    fd_close(fd) {
        try {
            const stream = SYSCALLS.getStreamFromFD(fd)
            const flags = stream.flags
            const path = stream.path
            FS.close(stream)
            // Don't run if we're currently syncing (because syncing will run this code)
            if (FS.syncFSRequests === 0) {
                // Then check that we're saving a savefile
                if (path.startsWith('/saves/') && flags & 3) {
                    FS.syncfs(err => {
                        if (err) {
                            console.log(err)
                        }
                    })
                }
            }
            return 0
        } catch (e) {
            if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e
            return e.errno
        }
    },

src/settings.js Outdated Show resolved Hide resolved
@sbc100
Copy link
Collaborator

sbc100 commented May 16, 2024

What do you think about enabling this by default?

@juj
Copy link
Collaborator Author

juj commented May 17, 2024

What do you think about enabling this by default?

Personally that would be ok for me, although I do worry that there might be some user projects that would be broken by such a change, in case they might have custom semantics for when the IndexedDB database would be synchronized. So maybe err to side of caution for now?

@sbc100
Copy link
Collaborator

sbc100 commented May 17, 2024

What do you think about enabling this by default?

Personally that would be ok for me, although I do worry that there might be some user projects that would be broken by such a change, in case they might have custom semantics for when the IndexedDB database would be synchronized. So maybe err to side of caution for now?

sgtm. We can always consider enabling by default later.

@juj juj enabled auto-merge (squash) May 21, 2024 14:55
@juj
Copy link
Collaborator Author

juj commented May 21, 2024

Any more reviews, or a ✅ ?

@sbc100 sbc100 requested review from kripken and tlively May 21, 2024 14:59
}
},

mount: (...args) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making this a mount option instead of a settings? (That would limit the scope of this chance to just this library file). Just an idea. I guess the downside would be a minor code size increase for idbfs users who don't need this feature, but I imagine it would be marginal.. since the FS code is so heavy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the FS code is quite heavy already, so I wouldn't include it in the aggressive minimal code size optimization domain.

I suppose it could be an option, I'll see about refactoring it to that form.

@juj juj disabled auto-merge May 21, 2024 15:06
src/library_idbfs.js Outdated Show resolved Hide resolved
return node;
};
// Also kick off persisting the filesystem on other operations that modify the filesystem.
mnt.node_ops.mkdir = (...args) => { var ret = memfs_node_ops.mkdir(...args); IDBFS.queuePersist(mnt.mount); return ret; };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you write these as comma expressions to avoid the return statement and curly braces?

 mnt.node_ops.mkdir   = (...args) =>  IDBFS.queuePersist(mnt.mount), memfs_node_ops.mkdir(...args);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, does that parse?

function f() { return 1; }
function g() { return 2; }
var foo = (...args) => f(), g();

gives a syntax error, though

function f() { return 1; }
function g() { return 2; }
var foo = (...args) => { return f(), g() };

works.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting. Looks like simple comma expression work: var foo = (...args) => f, g;.

More complex ones require braces I guess: var foo = (...args) => (f(), g());

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we be able to make this the default behavior rather than adding another setting?

Edit: already discussed.

@juj
Copy link
Collaborator Author

juj commented May 22, 2024

Updated code to make this a runtime setting.

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Looks like the PR title needs updating.

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth a ChangeLog entry?

I do think we should consider making this the default at some point. Perhaps we should reach out to existing users via the mailing list to see if this makes sense?

One possible way to make this the default and have folks opt out would be to have the public IDBFS.syncfs() assert if you its called when autoPersist is enabled?

juj added 8 commits May 23, 2024 14:35
…n IndedexDB mount to automatically persist the VFS to IndexedDB after closing any file that has been written to. This enables users to avoid needing to call fsync() to persist files to the filesystem.
…_sync to properly delete IndexedDB state for the test if test fails.
@juj juj changed the title Add new setting -sIDBFS_AUTO_PERSIST Add mount option { autoPersist: true } to IDBFS mount. May 23, 2024
@juj juj enabled auto-merge (squash) May 23, 2024 11:37
@juj juj merged commit 91b348d into emscripten-core:main May 23, 2024
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants