Table of Contents
Handling many peers with y-webrtc
Avoiding document fragmentation
Scaling peer-to-peer collaboration to many peers
Handling partitioned collaboration
Syncronizing after partition
Operation deduplication in Yjs
While collaboration between users has been a fixture of content management systems and web applications in general for many years, the prospect of true real-time, peer-to-peer collaboration remains relatively elusive despite the proliferation of new technologies over the past several years. Luckily, this may soon change thanks to the evolution of real-time collaboration frameworks like Yjs and the availability and level of browser support enjoyed by the new WebRTC protocol. With both Yjs and WebRTC, it is now within reach for all developers to build peer-to-peer collaborative editing for a variety of use cases.
Some time ago, I (Preston So, Editor in Chief at Tag1 and author of Decoupled Drupal in Practice) had the unique opportunity to join my colleagues Kevin Jahns (Real-Time Collaboration Systems Lead at Tag1 and founder and project lead of Yjs), Fabian Franz (Senior Technical Architect and Performance Lead at Tag1), and Michael Meyers (Managing Director at Tag1) for an exploration of decentralized collaboration enabled by the combination of Yjs and WebRTC. In this multi-part blog series, we examine some of the conclusions from that Tag1 Team Talks webinar and dig into how leveraging both Yjs and WebRTC can enable unexpected use cases in real-time collaboration between peers. In this third installment of that series, we ask a question familiar to anyone in peer-to-peer computing: How many peers can y-webrtc, Yjs' integration with WebRTC, support exactly?
As we discussed previously earlier in this blog series, WebRTC enables peer-to-peer communication by establishing direct connections between browsers situated on different networks. By the same token, when we create a session between many different peers at the same time, they will all establish direct connections with one another, thus creating a huge network. In this section, we take a closer look at some of the implications of peer-to-peer collaboration at scale.
As this scenario illustrates, the notion of hundreds of people working in the same document and collaborating through y-webrtc means that a single peer will be connected to hundreds of others, with hundreds of connections made between them. Consider a situation in which hundreds of editors are collaborating on a single document in real time. If one of the collaborators' connections fails, nothing goes awry, because as we saw in previous examinations of Yjs and real-time collaboration, all document operations will be forwarded to other peers as well.
However, an undesirable potential situation is one in which the size of the network requires separation into two separate networks while both networks remain connected to the same collaboration room. We need to avoid this outcome because documentation fragmentation, a situation avoided by the forwarding described in the previous paragraph, will occur when multiple networks occupy the same room. The importance of eschewing document fragmentation is the key reason why all peers are connected to one another by default in typical Yjs usage.
A scenario in which many peers have many direct connections with one another is a situation that scales to larger numbers of users relatively gracefully, up to a point. For example, y-webrtc can support up to twenty or thirty simultaneous peers on typical connections on a desktop or laptop computer. On mobile devices, however, fewer peers may be supportable, because peer-to-peer connections on mobile networks impose more restrictions and are by their nature slower.
Nonetheless, because all users in a peer-to-peer collaboration room receive all operations conducted on a network, all we truly need to ensure no document fragmentation is a single peer that is connected to all other peers that preserves the integrity of the full document. If that single connected peer is connected to all others, they receive all data and all operations that affect the nature of that data. Nonetheless, for the reasons described above, Kevin recommends refraining from allowing more than roughly 20-30 simultaneous connections on y-webrtc, though optimizations in the future are slated for development.
During our recent Tag1 Team Talks webinar, Fabian outlined an illustrative scenario that demonstrates how updates are transmitted to users in the case of collaboration rooms being partitioned, or separated due to a lack of connectivity between two groups of peers. Consider a scenario in which Ali leads one team in Atlanta and Beatriz leads another in Bratislava. Ali confers and collaborates regularly with his marketing team while simultaneously collaborating with Beatriz and her colleagues across the Atlantic Ocean.
Now, consider a series of events in which Ali's team and Beatriz's team disconnect from one another while working in the same document, perhaps due to the severing of key cables on the ocean floor. Key questions arise when handling such partitioned collaboration. In Atlanta, Ali's team collaborates to make multiple changes to the document being edited transatlantically. In Bratislava, meanwhile, Beatriz's team also continues to make multiple changes to the same document. While Ali's team sees all of their team's updates and Beatriz's team sees their own updates, what happens in Yjs when the cable is mended and all peers in Atlanta and Bratislava are reconnected to each other?
In this scenario in Yjs, as soon as one client from one partition (in this case, Atlanta) connects to another client from another partition (in this case, Bratislava), they synchronize their content with one another thanks to Yjs' sync capabilities, which handle conflict resolution among many other features. If the Atlanta team has created a lengthy document while the Bratislava team has created a significantly different lengthy document, it may no longer make sense to sync. For this reason, we need to ensure that the time required to resolve document fragmentation is not overly long.
To illustrate this further, consider a scenario in which one of Beatriz's team members, Charlotte, successfully syncs earlier than other collaborators by reestablishing a connection earlier, syncing all of the Atlanta team's changes, and syncing all of the Bratislava team's changes. Now, when Charlotte makes changes, how do her operations become recognized by the other peers who are only now reestablishing their connections to the network without incurring a so-called "sync storm"?
In this case, large differences between document versions may require transmission of large amounts of data. Consider a scenario in which a single peer is collaborating with a group that now has two massive partitions consisting of ten clients on one side of the Atlantic and ten clients on the other. If, suddenly, ten clients enter the collaboration room, we as that individual peer will need to sync with all ten clients simultaneously. However, thanks to Yjs' ability to recognize duplicate data, we will receive the same operations ten times, but Yjs will not apply those changes to the document by recognizing that the set of operations is identical to previous sets received.
This key characteristic of Yjs is essential, because peer-to-peer collaboration will inevitably involve the receipt of duplicates all the time, even when using a WebSocket connection that aims to minimize their prevalence. Every time a peer makes an update to a document that the server sends, all other peers will not only register that update on their own document versions but also send that same update back to you as a duplicate. But because each character is uniquely identified in Yjs, as we saw previously in prior discussions of Yjs, we always understand that we received an already defined character and that the update was already performed — thus saving further computation time.
Decentralized collaborative editing is fast becoming a reality thanks to accelerating innovation in decentralized applications and the new availability of protocols like WebRTC. Nonetheless, frameworks like the open-source Yjs are still required not only in order to enable conflict resolution between changes across peers but also to handle many simultaneous connections and partitions between groups of collaborators when they occur. Fortunately, thanks to the rich integration between Yjs and WebRTC represented by y-webrtc, many of these issues are no longer the challenges they once were.
In this blog post, we examined two scenarios that are common in the world of real-time collaboration between peers: when many peers are editing a single document and when connections are severed and reestablished between two groups of peers. We also inspected some of the other limitations on peer-to-peer collaboration in browsers like Google Chrome and in y-webrtc itself. In the next installment of this multi-part blog series, we take a deeper look at how y-webrtc handles many connections and some of the fascinating potential applications for y-webrtc in the collaboration space.