-
Notifications
You must be signed in to change notification settings - Fork 5
Sharing Concept Creating File ID on Initial Sharing Request
The second approach makes use of the protocol for adding, modifying and removing files on the own clients: Sharing a file or directory should be equally handled, meaning that a file offering request has to be sent to all other own clients, making sure, that no other client is sharing the same file at the same time.
Once this step has been accomplished, the PathObject from the ObjectStore is read and checked whether a file id is already existing (from an earlier share). If this did not happen beforehand, we can now safely create a new file id and send the ShareRequest (for the sharer's client (select only one)) and FileSharedRequest (for all own clients).
The client which receives the ShareRequest will then initiate a FileDemandExchange to fetch the shared file.
All own clients will persist the new sharer and the file id to their own object stores.
As also explained in the overview of approaches, there exists a scenario in which this approach is causing conflicts on the fileId. Imagine the following:
Two sets, each having two clients of the same user (C11, C12) and (C21, C22) are operating concurrently on
the same file, i.e. are trying to share the same file to an user. Due to lost network messages, they are not
able to communicate with each other. Now, if they share the file, two different fileIds will be generated and
therefore two different files on the sharer.
Updates made will be propagated only to one set of clients. Once both sets will get to know them, they get a conflict on the same file, having two different fileIds for the same original file.
Therefore, a different approach had to be developed
Current Structure of the ObjectStore
{
"relative": "SomeHash",
"relative/path": "SomeOtherHash",
"relative/path/to": "SomeOtherHashToo",
"relative/path/to/the": "SomeHashOfTheDir",
"relative/path/to/the/file.txt": "someHashOverTheContent"
}
Use a combination of two Maps:
Map<Key1, Value>
{
"relative": "hashToObject",
"relative/path": "hashToObject",
"relative/path/to": "hashToObject",
"relative/path/to/the": "hashToObject",
"relative/path/to/the/file.txt": "hashToObject"
}
The second map will be initialised only for shared files (having a shared file id)
Map<Key2, Value>
{
"UUID1": "hashToObject",
"UUID2": "hashToObject",
"UUID3": "hashToObject",
"UUID4": "hashToObject",
"UUID5": "hashToObject"
}
As before the first map contains the information where the PathObjects are stored for each file. As on changing the file system, nothing should differ from before.
-
Adding a sharer: Send a
FileSharedRequestto all own clients and negotiate the FileID. After this, propagate aShareRequestto one of the other user's client, containing the UUID of the file. This file is created in thesharedWithOthersfolder. The client will then initiate a FileDemandExchange. - Moving a file on the owner side: The file is moved on the owner's clients (as before), no event is sent to other users' clients.
- Moving a file on the sharer side within the sharedWithOthers-Folder: The file is moved, no events are propagated to the original owner. (Since the client could have files which the original, sharing client may not have, e.g. a shared directory from another user).
-
Deleting a file: The file is removed and a
DeleteEventis sent to all clients, incl. sharers.
By such an isolation of any filesystem's structure among different users, maintaining consistency will become much easier. Only the creation, modification and deletion of files have to be propagated to other users. Due to the identification with unique identifiers, these events are independent of a particular location on the filesystem. Issues with creating large nested folders on the sharer side will therefore not be present.
The following scenario should use as an example whereas Client1 resp. Client2 belong to different users.
The shared folders are called sharedWithOthers1 resp. sharedWithOthers2 to illustrate that these are different on each client. Actually, they will be called the same on all clients.
Client 1
========
|- dir11
| |
| |- innerDir11
| |
| |- innerDir12
| |
| |- file.txt
| |- sharedFile.txt (shared with Client2)
|
|- sharedWithOthers1
Client 2
=======
|- dir21
|
|
|- sharedWithOthers2
|
|- sharedFile.txt (shared from Client1)
This section only applies to sharers with write permissions.
Sharing a file
- Owner-Side: Start OfferExchange for File. Create FileID and add sharer to
sharedWithlist in ObjectStore. Propagate a ShareRequest to the new user. - Sharer-Side: Whenever a file is shared (e.g. Client1 shares the file
sharedFile.txtwith Client2), the shared copy is created in thesharedWithOthersfolder (e.g.sharedWithOthers2) using a FileDemandExchange.
Updating a shared file on the owner side
- Owner-Side: Modifying a shared file results in sending a
ModifyEventresp.ModifySharedPathto all clients and sharers. - Sharer-Side: Update the file
Updating a shared file on the sharer side
- Owner-Side: Map received
ModifySharedPathfrom sharer to correct file in own object store - Sharer-Side: Update file
Deleting a shared file
- Owner-Side: Propagate the delete event
- Sharer-Side: Delete the file in the
sharedWithMe-folder
Moving a file on the owner side
- Moving the whole shared folder (root shared folder)
- Owner-Side: Propagate move event to all own clients. Do not propagate the event to sharers
- Sharer-Side: No notification about a move
- Moving inside the shared folder
- Owner-Side: Propagate move event to all clients, incl. sharers
- Sharer-Side: Move the file inside the shared folder
- Moving away from the shared folder
- Owner-Side: Move the file from the shared folder away. Propagate a delete event to all sharers
- Sharer-Side: Delete the file from the
sharedWithMefolder
- Moving into a shared folder
- Owner-Side: Move the file into the shared folder. File/Dir gets the same sharing properties as its parent. Propagate a
CreateEventto all sharers, if necessary. - Sharer-Side: Create the file for the incoming request
- Owner-Side: Move the file into the shared folder. File/Dir gets the same sharing properties as its parent. Propagate a
Moving a file on the sharer side
- Moving the whole shared folder (root shared folder)
- Owner-Side: No notification
- Sharer-Side: Move the shared folder, only propagate move event to own clients
- Moving inside the shared folder
- Owner-Side: Move the file
- Sharer-Side: Move the file. Send
MoveEventto all clients, incl. sharers
- Moving away from the shared folder
- Owner-Side: Map move event to correct file. Remove all sharers from the file in the ObjectStore
- Sharer-Side: Move file to own (i.e. not shared) directory
- Moving into a shared folder
- Owner-Side: Receives the create event. Create the file.
- Sharer-Side: Move file into the shared folder. It gets the same permissions as the parent directory. Propagate
MoveEventto own clients but aCreateEventfor the sharers.
This section applies to sharers having only read permissions
Updating a shared file on the owner side
- Owner-Side: Modifying a shared file results in adjusting the modify event path for all sharers to
sharedWithMe/<file>. - Sharer-Side: Update the file (only if hash is equal, ignore incoming changes for changed files on read-only sharers)
Updating a shared file on the sharer side
- Owner-Side: Ignore update
- Sharer-Side: Update the file
Deleting a shared file
- Owner-Side: Ignore delete
- Sharer-Side: Delete the file in the
sharedWithMe-folder
Moving a file on the owner side
- Owner-Side: Propagate move event to all own clients. Do not propagate the event to sharers
- Sharer-Side: No notification about a move
Moving a file on the sharer side
- Owner-Side: Ignore move
- Sharer-Side: Move file to own (i.e. not shared) directory
- Commons
- Persistence Layer
- Versioning Layer
- Event Aggregation Layer
- Network Layer
- Core (this repository)
- End-User Client