Skip to content

Sharing Concept Creating File ID on Initial Sharing Request

Raphael Matile edited this page Jan 31, 2016 · 2 revisions

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.

Why this approach is not chosen

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

Modifications to the ObjectStore for this approach

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"
}

Proposed Structure of the ObjectStore

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"
}

Sharing files which are uniquely identified

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 FileSharedRequest to all own clients and negotiate the FileID. After this, propagate a ShareRequest to one of the other user's client, containing the UUID of the file. This file is created in the sharedWithOthers folder. 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 DeleteEvent is 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.

Scenario

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)

Sharers having Write Permissions

This section only applies to sharers with write permissions.

Sharing a file

  • Owner-Side: Start OfferExchange for File. Create FileID and add sharer to sharedWith list in ObjectStore. Propagate a ShareRequest to the new user.
  • Sharer-Side: Whenever a file is shared (e.g. Client1 shares the file sharedFile.txt with Client2), the shared copy is created in the sharedWithOthers folder (e.g. sharedWithOthers2) using a FileDemandExchange.

Updating a shared file on the owner side

  • Owner-Side: Modifying a shared file results in sending a ModifyEvent resp. ModifySharedPath to all clients and sharers.
  • Sharer-Side: Update the file

Updating a shared file on the sharer side

  • Owner-Side: Map received ModifySharedPath from 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 sharedWithMe folder
  • 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 CreateEvent to all sharers, if necessary.
    • Sharer-Side: Create the file for the incoming request

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 MoveEvent to 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 MoveEvent to own clients but a CreateEvent for the sharers.

Sharers having Read Permissions

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

Clone this wiki locally