textileio / go-textile

[DEPRECATED] Textile is a set of tools and infrastructure for building composable apps and services on the IPFS network
https://textile.io
MIT License
357 stars 43 forks source link

File Sync #586

Closed sanderpick closed 5 years ago

sanderpick commented 5 years ago

As per team call regarding the plan for camera roll sync:

sanderpick commented 5 years ago

In an effort to open up some of this design, I want to share my current thinking here. What we are after is something like GraphSync.

Goals

The current implementation is based on the idea of a "cafe request", and specifically "store" type cafe requests. Other types are for snapshot-ing and un-snapshot-ing threads, delivering a message to a peer, and un-storing. For each node / object in a graph, a store request is created. Currently, there is no intelligent grouping of these requests. (Actually, we do currently have a concept of grouping but it needs to change slightly as proposed below).

Proposal

sync2

A file(s) input creates a graph that needs to be synced. To avoid unbounded request sizes from giant file groups, we can break up the graph as follows:

This implies that the pinning of the block and the publishing of the block to the thread must be split into distinct steps. Once the Sync Group has been completely synced, the block can be "released" to the thread. This results in the following (this is already implemented):

  1. A "block message" is created for each member and added to the "block outbox" (a queue)
  2. An attempt is made to send the message (encrypted block) directly to the recipient peer
  3. If this fails, it is removed from this queue and used to create a cafe inbox request and is added to the cafe outbox (it does not need to be grouped with others)

Note: In practice, the block that is actually released may be newer since more recent actions may have generated blocks that were more quickly synced (perhaps not part of a large group).

Desktop

On desktop, we should be able to eventually use GraphSync when it's ready. Our current implementation functions over libp2p and performs work similar to bitswap's want list where blocks are only sent if they are needed. This is determined by a pre-request round-trip where the cafe can remove hashes from the the list of blocks that will be sent.

Mobile

On mobile, all requests must be handled by the background upload services on iOS/Android. This makes doing something like the want list approach a good bit harder. So, the first pass here does not care about bandwidth duplication. This means that we can make use of multipart requests for each "request group" above.

sanderpick commented 5 years ago

Call notes:

Call participants: @asutula, @sanderpick

sanderpick commented 5 years ago

Currently working on implementing a slightly tweaked interface for the cafe reqs. This can support desktop and mobile request handlers.

type CafeRequestStore interface {
    Queryable
    Add(req *pb.CafeRequest) error
    Get(id string) *pb.CafeRequest
    List(offset string, limit int) *pb.CafeRequestList
    ListGroups(offset string, limit int) []string
    ListCompletedSyncGroups() []string
    SyncGroupStatus(syncGroupId string) *pb.CafeRequestGroupStatus
    UpdateStatus(id string, status pb.CafeRequest_Status) error
    UpdateGroupStatus(group string, status pb.CafeRequest_Status) error
    Delete(id string) error
    DeleteByGroup(groupId string) error
    DeleteBySyncGroup(syncGroupId string) error
    DeleteByCafe(cafeId string) error
}