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

Syncing #62

Merged
merged 13 commits into from
Sep 20, 2019
Merged

Syncing #62

merged 13 commits into from
Sep 20, 2019

Conversation

ErikBjare
Copy link
Member

Started working on syncing

@ErikBjare
Copy link
Member Author

@johan-bjareholt Could I get some comments on this?

Copy link
Member

@johan-bjareholt johan-bjareholt left a comment

Choose a reason for hiding this comment

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

I need some more time to look into this, still don't fully understand what's going on.

src/sync.rs Outdated Show resolved Hide resolved
Copy link
Member

@johan-bjareholt johan-bjareholt left a comment

Choose a reason for hiding this comment

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

A good start.

We need some restructuring later though, such as move this out to a seperate "sync" folder instead of being inside "src" and then moving out everything in "src" into "core" and "server" or something like that. We don't want everything to become a huge monolith. This doesn't need to be done in this PR.

It would be good if you could modularize it a bit more and write it as multiple tests instead and just keep a non-functional main function for now until everything is properly implemented.

I've looked it though a bit and I think I (kind of) understand the flow of the program, I'm not sure if it's simply because I don't fully understand how it's supposed to work or if the functions are oddly split so I have a hard time understanding the overview.

src/datastore/datastore.rs Show resolved Hide resolved
src/sync.rs Outdated
}

// Sync events
// FIXME: Events are not being saved, does the datastore worker need more time before exit?
Copy link
Member

Choose a reason for hiding this comment

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

The events are probably not commited.
You could add a "ForceCommit" command to the datastore if you want.
In addition you could also add an "Stop" command which finishes up and then exits the thread and then the requester thread can wait for the worker thread to exit.

Copy link
Member Author

Choose a reason for hiding this comment

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

I fixed it by simply moving the references to the datastores out of the main function and then leaving a sleep in main to give it some time to commit (is this necessary though?).

Copy link
Member Author

Choose a reason for hiding this comment

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

While that kinda fixed it, it still leaves all kinds of unexpected behavior so until we add a ForceCommit or something I've just set commit: true when initializing the DatastoreInstance for now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nevermind, added the ForceCommit, was really easy.

Copy link
Member Author

@ErikBjare ErikBjare Sep 9, 2019

Choose a reason for hiding this comment

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

Still leads to loads of unexpected behavior though. For example: If I do a insert_events and then a get_event_count I expect it to return the new number, not the old one (there are a lot of cases like this).

The solution as I see it is to commit pending operations before a get operation. (or on every non-heartbeat command)

I would expect that if we ran the aw-server/aw-client integration tests targeting aw-server-rust we'd trigger many of these weird cases.

Copy link
Member

Choose a reason for hiding this comment

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

The solution as I see it is to commit pending operations before a get operation.

This is how the sqlite storage method in python does it, might be a good idea yes.

src/sync.rs Outdated Show resolved Hide resolved
Ok(Responses::BucketMap(ds.get_buckets()))
},
Commands::InsertEvents(bucketname, events) => {
ds.commit = true;
Copy link
Member

Choose a reason for hiding this comment

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

Remove

Copy link
Member Author

@ErikBjare ErikBjare Sep 9, 2019

Choose a reason for hiding this comment

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

I won't until we've fixed the commit-before-get. If I do I have to put ds.force_commit() after practically every ds.insert_events() which is really annoying and hard to debug.

src/datastore/datastore.rs Outdated Show resolved Hide resolved
src/sync_main.rs Outdated
// Needed to give the datastores some time to commit before program is shut down.
// 100ms isn't actually needed, seemed to work fine with as little as 10ms, but I'd rather give
// it some wiggleroom.
std::thread::sleep(std::time::Duration::from_millis(100));
Copy link
Member

Choose a reason for hiding this comment

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

In C you don't need to sleep but can wait for a thread to close down.

How to do it properly in Rust without any risk of deadlocks though I have no idea...

Copy link
Member Author

Choose a reason for hiding this comment

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

If you find a way we could always wait and have a timeout to avoid a deadlock.

src/sync.rs Outdated

/// Returns the sync-destination bucket for a given bucket, creates it if it doesn't exist.
fn get_or_create_sync_bucket(bucket_from: &Bucket, ds_to: &Datastore) -> Bucket {
// Ensure the bucket ID ends in "-synced"
Copy link
Member

Choose a reason for hiding this comment

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

Would be cool with a "synced" property to the buckets instead.

Copy link
Member

@johan-bjareholt johan-bjareholt left a comment

Choose a reason for hiding this comment

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

How is this all supposed to work when syncing while aw-server is running?
Will there be writes to the same sqlite file from two processes?

@ErikBjare
Copy link
Member Author

@johan-bjareholt The syncing could either happen in the same process, or in a separate process if all write-access to the local aw-server happens through the REST API (which is what I'm considering for the MVP).

Copy link
Member

@johan-bjareholt johan-bjareholt left a comment

Choose a reason for hiding this comment

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

After you have fixed the commit before get we can merge this.

The syncing code still needs some improvement, but as long as we don't break aw-server I'm fine with having merged prototype code.

@ErikBjare
Copy link
Member Author

@johan-bjareholt If it's not too much effort I'd like it if you fixed the commit-before-get. It shouldn't be too much work and I think you'd do a much better job (not to mention you'd do it a lot quicker).

@johan-bjareholt
Copy link
Member

@ErikBjare Have you tried to change the transaction behavior to IMMEDIATE instead of EXCLUSIVE?
That might actually solve the problem without having to do commits on every GetEvents as long as we only read one database and are the only ones writing to the other database (there has to be a clear master/slave scenario, which is a good thing anyway).

@ErikBjare
Copy link
Member Author

ErikBjare commented Sep 16, 2019

Have you tried to change the transaction behavior to IMMEDIATE instead of EXCLUSIVE?

Nope, the SQLite docs say that "EXCLUSIVE and IMMEDIATE are the same in WAL mode".


Can I merge this so we can get on with merging #65?

@johan-bjareholt
Copy link
Member

Feel free to merge, I don't approve of the syncing code yet but that's just a prototype. I don't approve of the ds.commit=true either but it's not broken and I can fix that in #65 so it's fine.

You just need to fix some conflict?

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.

2 participants