ഇവന്റ്-ഫോട്ടോ ആപ്പുകൾ വികസിപ്പിക്കുന്നവർക്ക്, ആളുകൾ തിങ്ങിനിറഞ്ഞ സ്ഥലങ്ങളിൽ ബ്രൗസർ അപ്ലോഡുകൾ തടസ്സമില്ലാതെ നടത്തുന്നതിനായി ഇപ്പോൾ കൃത്യമായ ഒരു ചെക്ക്ലിസ്റ്റ് ലഭ്യമാണ്. ഒരു ഉപയോക്താവ് വൈഫൈയിൽ നിന്ന് സെല്ലുലാർ നെറ്റ്വർക്കിലേക്ക് മാറാം, ഒപ്പം ഡസൻ കണക്കിന് ഉപകരണങ്ങൾ ഒരേ ഹോട്ട്സ്പോട്ടിനായി മത്സരിക്കുകയും ചെയ്തേക്കാം. ഒരു “upload complete” ടോസ്റ്റ് (toast) വന്നതിന് ശേഷം, ഫോൺ ലോക്ക് ചെയ്താലോ നെറ്റ്വർക്ക് തകരാറിലായാലോ പോലും ഫോട്ടോ നഷ്ടപ്പെടാതിരിക്കാൻ എന്തുചെയ്യണമെന്ന് ഈ ഗൈഡ് കാണിച്ചുതരുന്നു.
വിവാഹങ്ങളിലും ഉത്സവങ്ങളിലും സാധാരണ അപ്ലോഡുകൾ പരാജയപ്പെടുന്നത് എന്തുകൊണ്ട്
ഒരു ഓഫീസിൽ ലാപ്ടോപ്പ് സ്ഥിരതയുള്ള ഒരു ഇഥർനെറ്റ് ലിങ്കിലാണ് ഇരിക്കുന്നത്, അവിടെ ഒരു ഉപയോക്താവ് “send” ക്ലിക്ക് ചെയ്യുന്നു. എന്നാൽ ഒരു വിവാഹ റിസപ്ഷനിലോ സംഗീത മേളയിലോ ഇതേ പ്രവർത്തനം പ്രശ്നങ്ങളുടെ ഒരു പരമ്പരയ്ക്ക് കാരണമായേക്കാം: അതിഥികൾ സെറിമണി ഹാളിൽ നിന്ന് പാർക്കിംഗ് ഏരിയയിലേക്ക് നടക്കുന്നു, നൂറുകണക്കിന് ഫോണുകൾ കാരണം റൂട്ടർ താങ്ങാനാവാതെ വരുന്നു, അല്ലെങ്കിൽ ഫോൺ വൈഫൈ വിട്ട് സെല്ലുലാർ നെറ്റ്വർക്കിലേക്ക് മാറുന്നു. ബ്രൗസർ ഓരോ ബൈറ്റും സെർവറിലേക്ക് അയച്ചു കഴിഞ്ഞിട്ടുണ്ടാകാം, പക്ഷേ സെർവർ ആ ഫയൽ സ്റ്റോറേജിലേക്ക് മാറ്റിക്കാണില്ല. പ്രോഗ്രസ് ബാർ 100% എത്തിയ ഉടനെ UI വിജയം പ്രഖ്യാപിക്കുകയാണെങ്കിൽ, അതിഥി ഫോട്ടോ ഡിലീറ്റ് ചെയ്തേക്കാം, ഇത് സംഘാടകർക്ക് ഫയൽ നഷ്ടപ്പെടാൻ കാരണമാകും.
“വെറുതെ അപ്ലോഡ് ചെയ്യുക” എന്നതിലെ മറഞ്ഞിരിക്കുന്ന ചിലവ്
ഒരു ലളിതമായ സമീപനം അപ്ലോഡിനെ ഒരു സിംഗിൾ HTTP POST ആയി പരിഗണിക്കുന്നു. കണക്ഷൻ സ്ഥിരതയുള്ളപ്പോൾ ഇത് പ്രവർത്തിക്കും, എന്നാൽ തിരക്കേറിയ നെറ്റ്വർക്കിൽ ഓരോ തടസ്സവും ഫയൽ മുഴുവനായി ആദ്യം മുതൽ തുടങ്ങാൻ നിർബന്ധിക്കുന്നു. ഡസൻ കണക്കിന് ഫോണുകൾ ഒരേസമയം റീട്രൈ ചെയ്യുമ്പോൾ ഉപയോക്താക്കൾക്ക് നിരാശയുണ്ടാകുകയും ബാൻഡ്വിഡ്ത്ത് പെട്ടെന്ന് വർദ്ധിക്കുകയും ചെയ്യുന്നു. ഫയലിനെ ചങ്കുകളായി (chunks) വിഭജിക്കുന്നതും ഓരോ ഭാഗവും ട്രാക്ക് ചെയ്യുന്നതും സങ്കീർണ്ണത കൂട്ടുമെങ്കിലും, നെറ്റ്വർക്ക് മാറ്റങ്ങളെ അതിജീവിക്കുന്നതും കുറഞ്ഞ ചിലവിൽ സുഗമമായി ഫയൽ കൈമാറാൻ സഹായിക്കുന്നതുമായ ഒരു രീതിയാണിത്.
വീണ്ടും തുടങ്ങാൻ കഴിയുന്ന (resumable), ചങ്ക് അധിഷ്ഠിത (chunked) അപ്ലോഡ് സിസ്റ്റം നിർമ്മിക്കാം
താഴെ നൽകിയിരിക്കുന്നത് പ്രായോഗികമായ ഒരു ഘട്ടം ഘട്ടമായുള്ള രീതിയാണ്.
1. ഡാറ്റ ബ്രൗസറിൽ നിന്ന് പുറത്തുപോകുന്നതിന് മുമ്പ് ഒരു അപ്ലോഡ് ഐഡി (upload ID) നിർമ്മിക്കുക
ലോക്കലായി ഒരു യൂണിവേഴ്സൽ യുണീക് ഐഡന്റിഫയർ (UUID) നിർമ്മിക്കുകയും അത് ആദ്യത്തെ റിക്വസ്റ്റ് ആയി സെർവറിലേക്ക് അയക്കുകയും ചെയ്യുക. സെർവർ ആ ഐഡി ഉപയോഗിച്ച് ഒരു സെഷൻ രേഖപ്പെടുത്തുന്നു. ടൈമൗട്ട് കാരണം ബ്രൗസർ പിന്നീട് റീട്രൈ ചെയ്യുകയാണെങ്കിൽ, അത് അതേ UUID ഉൾപ്പെടുത്തുന്നു, ഇത് സെർവറിന് ആ സെഷൻ തിരിച്ചറിയാനും ഡ്യൂപ്ലിക്കേറ്റ് എൻട്രികൾ ഒഴിവാക്കാനും സഹായിക്കുന്നു. ഇത് വർക്ക്ഫ്ലോയെ idempotent ആക്കുന്നു—അതായത് ഒരേ റിക്വസ്റ്റ് ആവർത്തിക്കുന്നത് ദോഷകരമായ ഫലങ്ങൾ ഉണ്ടാക്കില്ല.
2. ഫയലിനെ 5 – 10 MB ചങ്കുകളായി (chunks) വിഭജിക്കുക
ചങ്ക് സൈസ് എന്നത് ഒരു ബാലൻസിംഗ് ആക്ട് ആണ്. ചെറിയ ചങ്കുകൾ (1 MB-യിൽ താഴെ) HTTP റിക്വസ്റ്റുകളുടെ എണ്ണവും അവയുടെ ഹെഡർ ഓവർഹെഡും വർദ്ധിപ്പിക്കുന്നു. വളരെ വലിയ ചങ്കുകൾ ഉപയോഗിച്ചാൽ, ഒരു തടസ്സം ഉണ്ടായാൽ വലിയൊരു ഭാഗം വീണ്ടും അയക്കേണ്ടി വരുന്നത് വലിയ നഷ്ടമുണ്ടാക്കും. സാധാരണ ഫോട്ടോകൾക്കും ചെറിയ വീഡിയോകൾക്കും 5 – 10 MB ആണ് അനുയോജ്യം: ഓരോ റിക്വസ്റ്റും UI റെസ്പോൺസീവ് ആയി നിലനിർത്താൻ പാകത്തിൽ വേഗത്തിൽ പൂർത്തിയാകുന്നു, അതേസമയം റിക്വസ്റ്റുകളുടെ എണ്ണവും നിയന്ത്രണവിധേയമായിരിക്കും.
3. പാരലൽ അപ്ലോഡുകളുടെ എണ്ണം പരിമിതപ്പെടുത്തുക
മൊബൈൽ ബ്രൗസറുകൾക്ക് ഒരേസമയം നിരവധി കണക്ഷനുകൾ തുറക്കാൻ കഴിയും, എന്നാൽ തിരക്കേറിയ വൈഫൈ നെറ്റ്വർക്കിൽ ഓരോ അധിക സ്ട്രീമും പരിമിതമായ ബാൻഡ്വിഡ്ത്തിനായി മത്സരിക്കുന്നു. എട്ട് സ്ട്രീമുകൾ മത്സരിക്കുന്നതിനേക്കാൾ രണ്ട് സ്ഥിരമായ സ്ട്രീമുകൾ മികച്ചതാണ്. കുറഞ്ഞ ബാൻഡ്വിഡ്ത്ത് സാഹചര്യങ്ങൾ തിരിച്ചറിയാനും കോൺകറൻസി (concurrency) സ്വയമേവ കുറയ്ക്കാനും navigator.connection API ഉപയോഗിക്കുക.
4. IndexedDB-യിൽ അപ്ലോഡ് സ്റ്റേറ്റ് സൂക്ഷിക്കുക
അപ്ലോഡ് ഐഡി, ഇതിനകം അയച്ച ചങ്കുകളുടെ പട്ടിക, സെർവർ അംഗീകരിച്ച ഓഫ്സെറ്റുകൾ (offsets) എന്നിവ ബ്രൗസറിലെ IndexedDB-യിൽ സൂക്ഷിക്കുക. പേജ് റീലോഡ് ആയാലോ ഉപയോക്താവ് ടാബ് അടച്ചാലോ, അടുത്ത തവണ ലോഡ് ചെയ്യുമ്പോൾ ക്ലയന്റിന് ഈ സ്റ്റേറ്റ് വീണ്ടെടുക്കാൻ കഴിയും. ഉപയോക്താവ് പേജ് വീണ്ടും തുറക്കുമ്പോൾ, അതേ ഫയൽ തിരഞ്ഞെടുക്കാൻ അവരോട് ആവശ്യപ്പെടുക; സൂക്ഷിച്ച മെറ്റാഡാറ്റ ഉപയോഗിച്ച് അപ്ലോഡ് ആദ്യം മുതൽ തുടങ്ങുന്നതിന് പകരം അവസാനമായി സ്ഥിരീകരിച്ച ചങ്കിൽ നിന്ന് തുടരാം.
5. navigator.onLine മാത്രമല്ല, യഥാർത്ഥ നെറ്റ്വർക്ക് മാറ്റങ്ങൾ തിരിച്ചറിയുക
കണക്ഷൻ ഉപയോഗശൂന്യമാണെങ്കിൽ പോലും navigator.onLine പലപ്പോഴും “online” എന്ന് കാണിക്കാറുണ്ട്. അതിനുപകരം, ഓരോ ചങ്കിനും ചെറിയൊരു റിക്വസ്റ്റ് ടൈമൗട്ട് (ഉദാഹരണത്തിന് 5 സെക്കൻഡ്) നിശ്ചയിക്കുക. ടൈമൗട്ട് സംഭവിച്ചാൽ, നെറ്റ്വർക്ക് നിലച്ചിരിക്കുന്നു എന്ന് കണക്കാക്കുക. കണക്റ്റിവിറ്റി തിരിച്ചുകിട്ടുമ്പോൾ, സെർവറിൽ നിലവിൽ ലഭ്യമായ ചങ്കുകളുടെ പട്ടിക ചോദിച്ചറിയുക, തുടർന്ന് വിട്ടുപോയ ഭാഗങ്ങൾ മാത്രം അപ്ലോഡ് ചെയ്യുക. ഇത് ചെറിയ തടസ്സങ്ങൾക്ക് ശേഷം ഡ്യൂപ്ലിക്കേറ്റ് ഡാറ്റ അയക്കുന്നത് ഒഴിവാക്കുന്നു.
6. റീട്രൈകൾക്കായി ജിറ്ററിനൊപ്പം (jitter) എക്സ്പോണൻഷ്യൽ ബാക്ക്ഓപ്പ് (exponential backoff) ഉപയോഗിക്കുക
നെറ്റ്വർക്ക് തിരിച്ചുവന്നതായി പല ഉപയോക്താക്കളുടെ ഉപകരണങ്ങളും അറിയുമ്പോൾ, അവയെല്ലാം ഒരേ സമയം റീട്രൈകൾ അയച്ചേക്കാം, ഇത് സെർവറിനെ തളർത്തും. എക്സ്പോണൻഷ്യൽ ബാക്ക്ഓപ്പ് ഓരോ റീട്രൈയും തൊട്ടുമുമ്പത്തേതിനേക്കാൾ കൂടുതൽ സമയം കാത്തിരിക്കാൻ നിർബന്ധിക്കുന്നു, ജിറ്റി (jitter) ഇതിലേക്ക് ഒരു ചെറിയ റാൻഡം ഓഫ്സെറ്റ് കൂടി ചേർക്കുന്നു. ഈ സംയോജനം റീട്രൈ ട്രാഫിക് കുറച്ചു സെക്കൻഡുകളിലായി വിന്യസിക്കുകയും പെട്ടെന്നുള്ള തിരക്ക് ഒഴിവാക്കുകയും ചെയ്യുന്നു.
7. വിവിധ തലങ്ങളിലുള്ള ഫീഡ്ബാക്ക് കാണിക്കുക
ഒരു മൂന്ന് തലങ്ങളുള്ള സ്റ്റാറ്റസ് ബാർ ഫയലിന്റെ യഥാർത്ഥ അവസ്ഥ വ്യക്തമാക്കുന്നു:
- Received – സെർവർ എല്ലാ ചങ്കുകളും ശേഖരിക്കുകയും ഫയൽ പൂർത്തിയായതായി അടയാളപ്പെടുത്തുകയും ചെയ്തിരിക്കുന്നു.
- Preparing – സെർവർ തംബ്നെയിലുകൾ നിർമ്മിക്കുകയോ വീഡിയോ ട്രാൻസ്കോഡിംഗ് നടത്തുകയോ ചെയ്യുന്നു.
- Available – സംഘാടകർക്ക് ഫയൽ കാണാനോ ഡൗൺലോഡ് ചെയ്യാനോ കഴിയും.
നിറത്തെ മാത്രം ആശ്രയിക്കുന്നത് ഒഴിവാക്കുക; സ്ക്രീൻ റീഡർ ഉപയോഗിക്കുന്നവർക്കും പുരോഗതി മനസ്സിലാക്കാൻ കഴിയുന്നതിനായി ഐക്കണുകൾക്കൊപ്പം ചെറിയ ടെക്സ്റ്റും നൽകുക.
എന്തൊക്കെ തെറ്റുകൾ സംഭവിക്കാം?
കൃത്യമായി രൂപകൽപ്പന ചെയ്ത ഒരു resumable upload പോലും ചില സങ്കീർണ്ണമായ സാഹചര്യങ്ങളിൽ (edge cases) തടസ്സപ്പെടാം.
ഇനി ശ്രദ്ധിക്കേണ്ട കാര്യങ്ങൾ
വെബ് പ്ലാറ്റ്ഫോം നിരന്തരം മാറിക്കൊണ്ടിരിക്കുകയാണ്.
ചുരുക്കത്തിൽ
ഓരോ ഭാഗവും ട്രാക്ക് ചെയ്യുന്നതും, സ്റ്റേറ്റ് (state) ലോക്കലായി സംഭരിക്കുന്നതും, ബുദ്ധിപരമായി വീണ്ടും ശ്രമിക്കുന്നതുമായ (retries) ഒരു resumable, chunked upload രീതി, അസ്ഥിരമായ ഇന്റർനെറ്റ് ശൃംഖലയെ പോലും അതിഥികളുടെ ഫോട്ടോകൾ കൈമാറുന്നതിനുള്ള വിശ്വസനീയമായ ഒരു മാർഗമാക്കി മാറ്റുന്നു. മുകളിൽ നൽകിയിരിക്കുന്ന ചെക്ക്ലിസ്റ്റ് നടപ്പിലാക്കുക.
