Skip to content

Syncing#62

Merged
ErikBjare merged 13 commits intomasterfrom
dev/syncing
Sep 20, 2019
Merged

Syncing#62
ErikBjare merged 13 commits intomasterfrom
dev/syncing

Conversation

@ErikBjare
Copy link
Copy Markdown
Member

Started working on syncing

@ErikBjare
Copy link
Copy Markdown
Member Author

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

Copy link
Copy Markdown
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.

Comment thread src/sync.rs Outdated
Copy link
Copy Markdown
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.

Comment thread src/datastore/datastore.rs
Comment thread src/sync.rs Outdated
}

// Sync events
// FIXME: Events are not being saved, does the datastore worker need more time before exit?
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.

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

Choose a reason for hiding this comment

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

Remove

Copy link
Copy Markdown
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.

Comment thread src/datastore/datastore.rs Outdated
Comment thread src/sync_main.rs
// 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
Copy Markdown
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
Copy Markdown
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.

Comment thread src/sync.rs

/// 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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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