ਰੀਅਲ-ਟਾਈਮ ਕੋਲੈਬੋਰੇਸ਼ਨ ਬਹੁਤ ਸੌਖੀ ਲੱਗਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸਦਾ ਅਸਲੀ ਚਿਹਰਾ ਨਹੀਂ ਦੇਖਦੇ। ਇੱਕ ਵਿਅਕਤੀ ਟਾਈਪ ਕਰਦਾ ਹੈ। ਦੂਜਾ ਤਿੰਨ ਪੈਰਾਗ੍ਰਾਫ ਉੱਪਰ ਇੱਕ ਲਾਈਨ ਮਿਟਾ ਦਿੰਦਾ ਹੈ। ਤੀਜਾ ਵਿਅਕਤੀ Stack Overflow ਤੋਂ ਇੱਕ ਸਨਿਪੈਟ ਪੇਸਟ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਤਰ੍ਹਾਂ ਦਸਤਾਵੇਜ਼ ਇੱਕ ਸਿੰਗਲ, ਇਕਸਾਰ ਸਥਿਤੀ ਵਿੱਚ ਸਥਾਪਿਤ ਹੋ ਜਾਂਦਾ ਹੈ। WebSockets ਜਾਂ distributed state ਵਿੱਚ ਪਹਿਲਾਂ ਤੋਂ ਕੋਈ ਅਨੁਭਵ ਨਾ ਹੋਣ ਦੇ ਬਾਵਜੂਦ, ਇਸ ਤਰ੍ਹਾਂ ਦੀ ਸਹਿਜਤਾ ਨੂੰ ਜ਼ੀਰੋ ਤੋਂ ਬਣਾਉਣਾ ਲਾਪਰਵਾਹੀ ਲੱਗ ਸਕਦਾ ਹੈ। ਪਰ ਇਹ ਅਸਲ ਵਿੱਚ ਸਿੱਖਣ ਦਾ ਸਹੀ ਤਰੀਕਾ ਵੀ ਲੱਗਦਾ ਹੈ।
ਇਹ ਪ੍ਰੋਜੈਕਟ ਜ਼ੀਰੋ ਤੋਂ ਸ਼ੁਰੂ ਹੁੰਦਾ ਹੈ। ਕੋਈ ਉਧਾਰ ਲਿਆ ਹੋਇਆ boilerplate ਨਹੀਂ। ਕੋਈ ਚਮਕਦਾਰ YouTube walkthroughs ਨਹੀਂ ਜਿੱਥੇ ਔਖੇ ਹਿੱਸਿਆਂ ਨੂੰ ਤੀਹ ਸਕਿੰਟ ਦੇ মন্ਟੇਜ ਵਿੱਚ ਛੱਡ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ। ਇਸਦਾ ਉਦੇਸ਼ ਇੱਕ collaborative code editor ਬਣਾਉਣਾ ਹੈ ਜਿੱਥੇ ਕਈ ਉਪਭੋਗਤਾ ਇੱਕੋ ਸਮੇਂ ਇੱਕੋ ਫਾਈਲ ਨੂੰ ਐਡਿਟ ਕਰ ਸਕਣ, ਅਤੇ ਇੱਕ ਦੂਜੇ ਦੇ ਬਦਲਾਅ—ਅਤੇ ਇੱਕ ਦੂਜੇ ਦੇ cursors—ਨੂੰ ਹੋਣ ਦੇ ਨਾਲ ਹੀ ਦੇਖ ਸਕਣ। ਉੱਥੇ ਪਹੁੰਚਣ ਲਈ transport layers, consistency models, ਅਤੇ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਖਰਾਬ ਕੀਤੇ ਬਿਨਾਂ concurrent edits ਨੂੰ ਮਰਜ ਕਰਨ ਦੀ ਔਖੀ ਸਮੱਸਿਆ ਨੂੰ ਸੁਲਝਾਉਣਾ ਪਵੇਗਾ।
"Real-Time" ਦਾ ਅਸਲ ਮਤਲਬ ਕੀ ਹੈ
ਜ਼ਿਆਦਾਤਰ ਵੈੱਬ ਐਪਲੀਕੇਸ਼ਨਾਂ request-response cycles ਨਾਲ ਸਹਿਜ ਹੁੰਦੀਆਂ ਹਨ। ਤੁਸੀਂ ਇੱਕ ਫਾਰਮ ਸਬਮਿਟ ਕਰਦੇ ਹੋ, ਸਰਵਰ ਇਸਨੂੰ ਸੇਵ ਕਰਦਾ ਹੈ, ਅਤੇ ਤੁਸੀਂ ਪੇਜ ਨੂੰ ਰਿਫ੍ਰੈਸ਼ ਕਰਦੇ ਹੋ। ਰੀਅਲ-ਟਾਈਮ ਕੋਲੈਬੋਰੇਸ਼ਨ ਉਸ ਸਮਝੌਤੇ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਤੋੜ ਦਿੰਦੀ ਹੈ। ਹਰ keystroke ਇੱਕ ਅਜਿਹੀ ਘਟਨਾ ਹੈ ਜੋ ਹਰ ਹੋਰ ਕਨੈਕਟਡ ਕਲਾਇੰਟ ਤੱਕ ਪਹੁੰਚਣੀ ਚਾਹੀਦੀ ਹੈ, ਆਮ ਤੌਰ 'ਤੇ ਮਿਲੀਸਕਿੰਡਾਂ ਵਿੱਚ, ਅਤੇ ਅਜਿਹੇ ਕ੍ਰਮ ਵਿੱਚ ਪਹੁੰਚਣੀ ਚਾਹੀਦੀ ਹੈ ਜੋ ਅਰਥ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖੇ।
WebSockets ਇੱਥੇ ਸਪੱਸ਼ਟ transport ਚੋਣ ਹਨ ਕਿਉਂਕਿ ਉਹ ਕਲਾਇੰਟ ਅਤੇ ਸਰਵਰ ਵਿਚਕਾਰ ਇੱਕ persistent, full-duplex ਕਨੈਕਸ਼ਨ ਬਣਾਈ ਰੱਖਦੇ ਹਨ। HTTP polling ਦੇ ਉਲਟ, ਜੋ ਹਰ ਕੁਝ ਸਕਿੰਟਾਂ ਬਾਅਦ "ਕੁਝ ਨਵਾਂ ਹੈ?" ਪੁੱਛ ਕੇ ਬੈਂਡਵਿਡਥ ਬਰਬਾਦ ਕਰਦਾ ਹੈ, ਇੱਕ WebSocket ਖੁੱਲ੍ਹਾ ਰਹਿੰਦਾ ਹੈ। ਜਦੋਂ ਯੂਜ਼ਰ A ਇੱਕ semicolon ਟਾਈਪ ਕਰਦਾ ਹੈ, ਤਾਂ ਉਹ ਅੱਖਰ ਇੱਕ ਮੈਸੇਜ ਬਣ ਜਾਂਦਾ ਹੈ ਜੋ ਸਾਕਟ ਰਾਹੀਂ ਇੱਕ ਕੇਂਦਰੀ ਸਰਵਰ ਤੱਕ ਜਾਂਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਯੂਜ਼ਰ B ਅਤੇ C ਤੱਕ ਫੈਲ ਜਾਂਦਾ ਹੈ। ਉਹ ਹਿੱਸਾ ਕਾਫ਼ੀ ਸਿੱਧਾ ਹੈ।
ਔਖਾ ਹਿੱਸਾ ਉਹ ਹੈ ਜੋ ਉਦੋਂ ਹੁੰਦਾ ਹੈ ਜਦੋਂ B ਅਤੇ C ਬਿਲਕੁਲ ਇੱਕੋ ਸਮੇਂ ਟਾਈਪ ਕਰਦੇ ਹਨ। ਜੇਕਰ ਦੋਵੇਂ ਬਦਲਾਅ ਲਗਭਗ ਇੱਕੋ ਸਮੇਂ ਸਰਵਰ 'ਤੇ ਪਹੁੰਚਦੇ ਹਨ, ਤਾਂ ਕਿਹੜਾ ਜਿੱਤੇਗਾ? ਜੇਕਰ ਤੁਸੀਂ ਸਿਰਫ਼ ਆਉਣ ਦੇ ਕ੍ਰਮ ਵਿੱਚ ਮੈਸੇਜ ਭੇਜਦੇ ਹੋ, ਤਾਂ ਅੱਖਰਾਂ ਦੇ ਗੁੰਮ ਹੋਣ ਜਾਂ ਟੈਕਸਟ ਦੇ ਉਲਝ ਜਾਣ ਦਾ ਖਤਰਾ ਰਹਿੰਦਾ ਹੈ। Naive last-write-wins ਰਣਨੀਤੀਆਂ ਅਸਫਲ ਰਹਿੰਦੀਆਂ ਹਨ ਕਿਉਂਕਿ ਉਹ ਇਰਾਦੇ (intent) ਨੂੰ ਨਜ਼ਰਅੰਦਾਜ਼ ਕਰਦੀਆਂ ਹਨ। ਜੇਕਰ ਮੈਂ ਲਾਈਨ ਇੱਕ ਦੀ ਸ਼ੁਰੂਆਤ ਵਿੱਚ "hello" ਟਾਈਪ ਕਰਦਾ ਹਾਂ ਜਦੋਂ ਕਿ ਤੁਸੀਂ ਲਾਈਨ ਇੱਕ ਦੀ ਸ਼ੁਰੂਆਤ ਵਿੱਚ "world" ਟਾਈਪ ਕਰਦੇ ਹੋ, ਤਾਂ ਨਤੀਜਾ ਕੋਈ ਟਕਰਾਅ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਜਿੱਥੇ ਸਾਡੇ ਵਿੱਚੋਂ ਇੱਕ ਮਿਟ ਜਾਵੇ। ਇਹ ਨਿਰਧਾਰਤ ਤੌਰ 'ਤੇ ਚੁਣਿਆ ਹੋਇਆ "helloworld" ਜਾਂ "worldhello" ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ। ਇਸ ਨੂੰ ਹਾਸਲ ਕਰਨ ਲਈ ਇੱਕ ਅਜਿਹੀ synchronization strategy ਦੀ ਲੋੜ ਹੈ ਜੋ ਦਸਤਾਵੇਜ਼ ਦੀ ਬਣਤਰ ਨੂੰ ਸਮਝਦੀ ਹੋਵੇ।
ਜ਼ੀਰੋ ਤੋਂ ਸ਼ੁਰੂ ਕਰਨਾ ਕਿਉਂ ਮਹੱਤਵਪੂਰਨ ਹੈ
ਅਜਿਹੇ ਉੱਤਮ ਫਰੇਮਵਰਕ ਹਨ ਜੋ ਇਸ ਗੁੰਝਲਤਾ ਨੂੰ ਲੁਕਾ ਦਿੰਦੇ ਹਨ। Yjs, Automerge, ਅਤੇ Socket.IO ਇਸ ਮੁਸ਼ਕਲ ਨੂੰ ਘਟਾ ਸਕਦੇ ਹਨ ਅਤੇ ਇੱਕ ਦੁਪਹਿਰ ਵਿੱਚ ਇੱਕ ਕੰਮ ਕਰਦਾ ਪ੍ਰੋਟੋਟਾਈਪ ਤਿਆਰ ਕਰ ਸਕਦੇ ਹਨ। ਪਰ ਅੰਦਰੂਨੀ primitives ਨੂੰ ਸਮਝੇ ਬਿਨਾਂ ਉਹਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨਾ ਉਦੋਂ ਵਾਂਗ ਹੈ ਜਿਵੇਂ ਕਿ ਯੰਤਰਾਂ (instruments) ਨੂੰ ਪੜ੍ਹਨਾ ਜਾਣੇ ਬਿਨਾਂ ਆਟੋਪਾਇਲਟ 'ਤੇ ਜਹਾਜ਼ ਉਡਾਉਣਾ। ਜਦੋਂ ਹਲਚਲ (turbulence) ਆਉਂਦੀ ਹੈ—ਅਤੇ distributed systems ਵਿੱਚ, ਇਹ ਹਮੇਸ਼ਾ ਆਉਂਦੀ ਹੈ—ਤੁਹਾਨੂੰ ਇਹ ਜਾਣਨ ਦੀ ਲੋੜ ਹੈ ਕਿ ਸਮੱਸਿਆ ਤੁਹਾਡੇ network layer ਵਿੱਚ ਹੈ, ਤੁਹਾਡੇ conflict resolution ਵਿੱਚ ਹੈ, ਜਾਂ ਤੁਹਾਡੇ data model ਵਿੱਚ ਹੈ।
ਇੱਥੇ ਵਚਨਬੱਧਤਾ ਲਾਇਬ੍ਰੇਰੀਆਂ 'ਤੇ ਨਿਰਭਰ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਸੰਕਲਪਾਂ ਨੂੰ ਸਿੱਖਣ ਦੀ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਮੈਨੂਅਲੀ ਇਹ ਸਮਝਣਾ ਕਿ ਕੀ ਹੁੰਦਾ ਹੈ ਜਦੋਂ:
- ਇੱਕ ਕਲਾਇੰਟ keystroke ਦੇ ਵਿਚਕਾਰ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਂਦਾ ਹੈ ਅਤੇ ਦਸ ਸਕਿੰਟ ਬਾਅਦ ਦੁਬਾਰਾ ਕਨੈਕਟ ਹੋ ਜਾਂਦਾ ਹੈ
- ਦੋ ਉਪਭੋਗਤਾ ਇੱਕੋ ਸਮੇਂ ਇੱਕੋ cursor position 'ਤੇ ਟੈਕਸਟ ਇਨਸਰਟ ਕਰਦੇ ਹਨ
- ਇੱਕ ਉਪਭੋਗਤਾ ਇੱਕ ਬਲਾਕ ਨੂੰ ਮਿਟਾ ਦਿੰਦਾ ਹੈ ਜਿਸ ਨੂੰ ਦੂਜਾ ਉਪਭੋਗਤਾ ਸਰਗਰਮ ਰੂਪ ਵਿੱਚ ਐਡਿਟ ਕਰ ਰਿਹਾ ਹੈ
- ਸਰਵਰ ਕ੍ਰੈਸ਼ ਹੋ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇੱਕ ਨਵੇਂ ਨੋਡ ਨੂੰ ਜ਼ੀਰੋ ਤੋਂ ਦਸਤਾਵੇਜ਼ ਦੀ ਸਥਿਤੀ ਨੂੰ ਮੁੜ ਸਿਰਜਣਾ ਪੈਂਦਾ ਹੈ
Operational Transformation (OT) ਅਤੇ Conflict-free Replicated Data Types (CRDTs) ਇਹਨਾਂ ਸਮੱਸਿਆਵਾਂ ਦੇ ਹੱਲ ਦੀਆਂ ਦੋ ਪ੍ਰਮੁੱਖ ਸ਼੍ਰੇਣੀਆਂ ਹਨ। Google Docs ਨੇ ਆਪਣਾ ਸ਼ੁਰੂਆਤੀ ਆਰਕੀਟੈਕਚਰ OT 'ਤੇ ਬਣਾਇਆ ਸੀ, ਜਿਸ ਲਈ ਉਹਨਾਂ ਨੂੰ ਲਾਗੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਕੇਂਦਰੀ ਸਰਵਰ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ ਜੋ ਆਪਰੇਸ਼ਨਾਂ ਨੂੰ ਇੱਕ ਦੂਜੇ ਦੇ ਵਿਰੁੱਧ ਬਦਲਦਾ ਹੈ। ਇਸਦੇ ਉਲਟ, CRDTs ਨੂੰ ਇਸ ਤਰ੍ਹਾਂ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਹੈ ਕਿ concurrent updates ਨੂੰ ਤਾਲਮੇਲ ਤੋਂ ਬਿਨਾਂ ਸਥਾਨਕ ਤੌਰ 'ਤੇ ਮਰਜ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ, ਜੋ ਉਹਨਾਂ ਨੂੰ peer-to-peer ਜਾਂ edge-based ਸੈੱਟਅੱਪਾਂ ਲਈ ਆਕਰਸ਼ਕ ਬਣਾਉਂਦਾ ਹੈ। ਉਹਨਾਂ ਵਿੱਚੋਂ ਕਿਸੇ ਇੱਕ ਨੂੰ ਚੁਣਨਾ—ਜਾਂ ਹਾਈਬ੍ਰਿਡ ਪਹੁੰਚਾਂ—ਤੁਹਾਡੇ ਤੋਂ ਮੈਮੋਰੀ ਦੀ ਵਰਤੋਂ, convergence guarantees, ਅਤੇ implementation complexity ਵਿੱਚ ਉਹ
ਉਮੀਦਾਂ ਨੂੰ ਇਮਾਨਦਾਰੀ ਨਾਲ ਤੈਅ ਕੀਤਾ ਗਿਆ ਹੈ। ਅਜਿਹੇ ਸਮੇਂ ਵੀ ਆਉਣਗੇ ਜਦੋਂ ਕੁਝ ਵੀ ਕੰਮ ਨਹੀਂ ਕਰੇਗਾ। ਪਹਿਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਟੈਕਸਟ ਬਦਲਾਅ ਨੂੰ ਦਰਸਾਉਣ ਲਈ ਸਧਾਰਨ JSON patches ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ, ਪਰ ਫਿਰ ਇਹ ਪਤਾ ਲੱਗ ਸਕਦਾ ਹੈ ਕਿ JSON ਵਿੱਚ "ਪੈਰਾਗ੍ਰਾਫ ਵਿੱਚ ਇੰਡੈਕਸ 5" ਵਰਗੀ ਕੋਈ ਧਾਰਨਾ ਨਹੀਂ ਹੈ, ਇਸ ਲਈ ਇੱਕੋ ਇੰਡੈਕਸ 'ਤੇ ਦੋ ਸਮਾਂਵਾਨ (concurrent) ਇਨਸਰਸ਼ਨ ਇੱਕ ਦੂਜੇ ਨੂੰ ਮਿਲਾਉਣ ਦੀ ਬਜਾਏ ਓਵਰਰਾਈਟ ਕਰ ਦਿੰਦੇ ਹਨ। ਦੂਜੀ ਕੋਸ਼ਿਸ਼ ਇੱਕ ਕਸਟਮ ਲੀਨੀਅਰ ਹਿਸਟਰੀ ਲੌਗ (linear history log) ਬਣਾ ਸਕਦੀ ਹੈ, ਪਰ ਫਿਰ ਇਹ ਅਹਿਸਾਸ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਜਦੋਂ ਦਸਤਾਵੇਜ਼ ਵਧਦਾ ਹੈ ਤਾਂ ਉਸ ਲੌਗ ਨੂੰ ਦੁਬਾਰਾ ਚਲਾਉਣਾ (replaying) Big O ਦਾ ਇੱਕ ਭਿਆਨਕ кошਮਾਰ ਬਣ ਜਾਂਦਾ ਹੈ। ਤੀਜੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ WebSockets ਨੂੰ ਸਥਾਨਕ ਤੌਰ 'ਤੇ ਚਲਾਇਆ ਜਾ ਸਕਦਾ ਹੈ, ਪਰ ਅਸਲ ਨੈੱਟਵਰਕ 'ਤੇ ਇਹ ਫੇਲ੍ਹ ਹੋ ਸਕਦਾ ਹੈ ਜਿੱਥੇ ਪੈਕੇਟ ਲੋਸ (packet loss) ਅਤੇ ਵਧਦੀ-ਘਟਦੀ ਲੈਟੈਂਸੀ (latency) ਨਿਯਮਾਂ ਨੂੰ ਬਦਲ ਦਿੰਦੀ ਹੈ।
ਉਹ ਰੁਕਾਵਟ ਹੀ ਅਸਲ ਮਕਸਦ ਹੈ। ਇੱਕ ਕੰਮ ਕਰਦੇ ਰੈਪੋਜ਼ੀਟਰੀ (repository) ਨੂੰ ਕਾਪੀ ਕਰਨ ਨਾਲ ਇਸ ਗੱਲ ਦੀ ਜਾਂਚ ਨਹੀਂ ਹੋਵੇਗੀ ਕਿ ਕਿਊ (queue) ਉਸ ਖਾਸ ਕ੍ਰਮ ਵਿੱਚ ਕਿਉਂ ਖਾਲੀ ਹੁੰਦੀ ਹੈ, ਜਾਂ ਸਰਵਰ ਵਰਜ਼ਨ ਵੈਕਟਰ (version vector) ਕਿਉਂ ਬਣਾਈ ਰੱਖਦਾ ਹੈ। ਇੱਕੋ ਕੰਪੋਨੈਂਟ ਨੂੰ ਤਿੰਨ ਵਾਰ ਦੁਬਾਰਾ ਬਣਾਉਣਾ ਹੌਲੀ ਹੈ, ਪਰ ਇਹ ਇਸ ਗੱਲ ਦੀ ਸਮਝ ਬਣਾਉਣ ਲਈ ਮਜਬੂਰ ਕਰਦਾ ਹੈ ਕਿ ਫਰੇਮਵਰਕ ਕੀ ਕਰਦਾ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਆਪਣੇ ਲੌਜਿਕ (logic) ਨੂੰ ਕੀ ਸੰਭਾਲਣਾ ਚਾਹੀਦਾ ਹੈ।
ਇਸ ਪ੍ਰਕਿਰਿਆ ਦਾ ਦਸਤਾਵੇਜ਼ੀਕਰਨ (documentation) ਸਿਰਫ਼ ਸਫਲਤਾਵਾਂ ਦੀ ਇੱਕ ਰੀਲ ਨਹੀਂ ਹੋਵੇਗੀ। ਇਸ ਵਿੱਚ ਗਲਤ ਰਾਹ ਵੀ ਸ਼ਾਮਲ ਹੋਣਗੇ। ਉਦਾਹਰਨ ਲਈ, ਪ੍ਰੈਜ਼ੈਂਸ ਅਵੇਅਰਨੈੱਸ (presence awareness) ਬਣਾਉਣਾ—ਇਹ ਜਾਣਨਾ ਕਿ ਕੌਣ ਆਨਲਾਈਨ ਹੈ ਅਤੇ ਉਹਨਾਂ ਦਾ ਕਰਸਰ (cursor) ਕਿੱਥੇ ਹੈ—ਇੱਕ ਸੁੰਦਰ ਦਿਖਣ ਵਾਲਾ ਫੀਚਰ ਲੱਗਦਾ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਹਾਨੂੰ ਇਹ ਅਹਿਸਾਸ ਨਹੀਂ ਹੁੰਦਾ ਕਿ ਇਹ ਟੈਕਸਟ ਦੀ ਤਰ੍ਹਾਂ ਹੀ ਉਸੇ ਕੰਸਿਸਟੈਂਸੀ ਮਾਡਲ (consistency model) 'ਤੇ ਨਿਰਭਰ ਕਰਦਾ ਹੈ। ਜੇਕਰ ਯੂਜ਼ਰ A, ਯੂਜ਼ਰ B ਦੇ ਕਰਸਰ ਨੂੰ ਕਾਲਮ 10 'ਤੇ ਦੇਖਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਯੂਜ਼ਰ B ਚਾਰ ਅੱਖਰ ਇਨਸਰਟ ਕਰਦਾ ਹੈ, ਤਾਂ ਉਹ ਕਰਸਰ ਕਿੱਥੇ ਜਾਵੇਗਾ? ਦਸਤਾਵੇਜ਼ ਟੋਪੋਲੋਜੀ (document topology) ਦੀ ਸਾਂਝੀ ਸਮਝ ਤੋਂ ਬਿਨਾਂ, ਪ੍ਰੈਜ਼ੈਂਸ ਡੇਟਾ ਅਸਲੀਅਤ ਤੋਂ ਭਟਕ ਜਾਂਦਾ ਹੈ। ਇਸ ਨੂੰ ਹੱਲ ਕਰਨ ਲਈ ਕਰਸਰ ਦੀ ਸਥਿਤੀ ਨੂੰ ਅਸਲ ਡੇਟਾ ਸਟ੍ਰਕਚਰ ਦੀ ਪਛਾਣ (identity) ਨਾਲ ਜੋੜਨਾ ਪਵੇਗਾ, ਨਾ ਕਿ ਸਿਰਫ਼ ਇਸਦੇ ਨੰਬਰਕਲ ਇੰਡੈਕਸ ਨਾਲ। ਇਹ ਉਹ ਕਿਸਮ ਦੇ ਵੇਰਵੇ ਹਨ ਜਿਨ੍ਹਾਂ ਨੂੰ ਟਿਊਟੋਰਿਅਲ (tutorials) ਵਿੱਚ ਛੱਡ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ ਕਿਉਂਕਿ ਉਹ ਉਬਾਊ ਹੁੰਦੇ ਹਨ, ਇਸ ਲਈ ਨਹੀਂ ਕਿ ਉਹ ਮਹੱਤਵਪੂਰਨ ਨਹੀਂ ਹਨ।
ਅੱਗੇ ਕੀ ਆਵੇਗਾ
ਤੁਰੰਤ ਰੋਡਮੈਪ ਜਾਣਬੁੱਝ ਕੇ ਸੀਮਤ ਰੱਖਿਆ ਗਿਆ ਹੈ। ਪਹਿਲੇ ਪੜਾਅ (milestones) ਇਹ ਹੋਣਗੇ:
- ਇੱਕ ਰਅ (raw) WebSocket ਸਰਵਰ ਜੋ ਅੱਖਰਾਂ ਦੀਆਂ ਘਟਨਾਵਾਂ (character events) ਨੂੰ ਈਕੋ (echo) ਕਰੇ, ਤਾਂ ਜੋ ਲੈਟੈਂਸੀ ਅਤੇ ਕਨੈਕਸ਼ਨ ਲਾਈਫਸਾਈਕਲ ਨੂੰ ਸਿੱਧੇ ਤੌਰ 'ਤੇ ਮਹਿਸੂਸ ਕੀਤਾ ਜਾ ਸਕੇ
- ਕਲਾਇੰਟ 'ਤੇ ਇੱਕ ਸਧਾਰਨ ਸਟ੍ਰਿੰਗ ਬਫਰ (string buffer) ਤਾਂ ਜੋ ਇਹ ਸਮਝਿਆ ਜਾ ਸਕੇ ਕਿ ਕੰਕਰੈਂਸੀ (concurrency) ਦੇ ਅਧੀਨ ਸਧਾਰਨ ਇਨਸਰਸ਼ਨ ਕ੍ਰਮ ਕਿਉਂ ਅਸਫਲ ਹੁੰਦਾ ਹੈ
- ਕ੍ਰਮਵਾਰ ਸੀਕੁਐਂਸਾਂ (ordered sequences) ਲਈ ਸ਼ੁਰੂ ਤੋਂ ਬਣਾਇਆ ਗਿਆ ਇੱਕ CRDT, ਭਾਵੇਂ ਉਹ ਕਿੰਨਾ ਵੀ ਅਕੁਸ਼ਲ ਕਿਉਂ ਨਾ ਹੋਵੇ, ਤਾਂ ਜੋ ਕਮਿਊਟੇਟਿਵ ਪ੍ਰਾਪਰਟੀ (commutative property) ਨੂੰ ਅਮਲੀ ਰੂਪ ਵਿੱਚ ਦੇਖਿਆ ਜਾ ਸਕੇ
- ਇੱਕ ਅਸਲ ਕੋਡ ਐਡੀਟਰ (code editor) ਜਿਵੇਂ ਕਿ CodeMirror ਜਾਂ Monaco ਨਾਲ ਹੌਲੀ-ਹੌਲੀ ਇੱਕੀਕਰਨ (integration), ਤਾਂ ਜੋ ਐਡੀਟਰ ਦੇ ਇੰਪੈਰੇਟਿਵ API (imperative API) ਅਤੇ ਓਪਰੇਸ਼ਨਲ ਹਿਸਟਰੀ ਦੀ ਫੰਕਸ਼ਨਲ ਪ੍ਰਕਿਰਤੀ ਦੇ ਵਿਚਕਾਰ ਅਸੰਗਤੀ ਨਾਲ ਨਜਿੱਠਿਆ ਜਾ ਸਕੇ
ਹਰ ਕਦਮ ਦੇ ਨਾਲ ਇੱਕ ਲਿਖਤੀ ਤਰਕ (rationale) ਹੋਵੇਗਾ। ਇਹ ਪਹੁੰਚ ਕਿਉਂ ਅਤੇ ਉਹ ਕਿਉਂ ਨਹੀਂ? ਕਿਹੜੀਆਂ ਧਾਰਨਾਵਾਂ ਗਲਤ ਸਾਬਤ ਹੋਈਆਂ? ਕਿਹੜੀ ਐਬਸਟਰੈਕਸ਼ਨ (abstraction) ਲੀਕ ਹੋਈ?
ਇੱਕ ਅਸਲ ਸਿੱਖਿਆ
WebSockets ਜਾਂ CRDTs ਵਿੱਚ ਤਜਰਬੇ ਤੋਂ ਬਿਨਾਂ ਅਜਿਹਾ ਪ੍ਰੋਜੈਕਟ ਸ਼ੁਰੂ ਕਰਨਾ ਡਰਾਉਣਾ ਲੱਗ ਸਕਦਾ ਹੈ, ਪਰ ਮਾਹਰਤਾ ਅਕਸਰ ਬਿਹਤਰ ਲੇਬਲਾਂ ਦੇ ਨਾਲ ਵਾਰ-ਵਾਰ ਹੋਣ ਵਾਲੀ ਉਲਝਣ ਹੀ ਹੁੰਦੀ ਹੈ। ਉਦੇਸ਼ ਤੇਜ਼ੀ ਨਾਲ ਖਤਮ ਕਰਨਾ ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਅਜਿਹਾ ਸਿਸਟਮ ਹੈ ਜਿਸਦਾ ਵਿਵਹਾਰ ਅਨੁਮਾਨਿਤ ਹੈ ਕਿਉਂਕਿ ਹਰ ਲੇਅਰ ਨੂੰ ਉਮੀਦ ਨਾਲ ਇੰਪੋਰਟ ਕਰਨ ਦੀ ਬਜਾਏ ਇਰਾਦੇ ਨਾਲ ਬਣਾਇਆ ਗਿਆ ਸੀ।
ਜੇਕਰ ਤੁਸੀਂ ਪਹਿਲਾਂ ਕਦੇ ਕੋਲੈਬੋਰੇਟਿਵ ਸਾਫਟਵੇਅਰ (collaborative software) ਬਣਾਇਆ ਹੈ—ਚਾਹੇ ਉਹ ਟੈਕਸਟ ਐਡੀਟਰ ਹੋਵੇ, ਡਿਜ਼ਾਈਨ ਟੂਲ ਹੋਵੇ, ਜਾਂ ਗੇਮ ਸਟੇਟ ਸਿੰਕ ਇੰਜਣ (game state sync engine) ਹੋਵੇ—ਉਹ ਅਸਫਲਤਾਵਾਂ ਸਾਂਝੀਆਂ ਕਰੋ ਜਿਨ੍ਹਾਂ ਨੇ ਤੁਹਾਨੂੰ ਹੈਰਾਨ ਕਰ ਦਿੱਤਾ ਸੀ। ਜੇਕਰ ਤੁਸੀਂ ਵੀ ਇਹ ਸਿਸਟਮ ਸਿੱਖ ਰਹੇ ਹੋ, ਤਾਂ ਸਾਡੇ ਨਾਲ ਜੁੜੋ। ਕੋਡ ਹੌਲੀ-ਹੌਲੀ ਆਵੇਗਾ, ਅਤੇ ਇਸਨੂੰ ਅਕਸਰ ਦੁਬਾਰਾ ਲਿਖਿਆ ਜਾਵੇਗਾ। ਦਿਨ 0 ਹੁਣ ਸ਼ੁਰੂ ਹੁੰਦਾ ਹੈ।
