ചാനലുകളിലൂടെ Go Concurrency-യിൽ പ്രാവീണ്യം നേടുക
ഞാൻ ഒരിക്കൽ Go-യിൽ ഒരു ഇമേജ് പ്രോസസ്സിംഗ് പൈപ്പ്ലൈൻ നിർമ്മിച്ചിരുന്നു.
ഓരോ ഘട്ടത്തിനും ഞാൻ goroutines ഉപയോഗിച്ചു. അവയെ ചാനലുകൾ (channels) ഉപയോഗിച്ച് ബന്ധിപ്പിച്ചു. ഞാൻ റൺ ചെയ്തു.
പ്രോഗ്രാം ഫ്രീസ് ആയി. മെമ്മറി ഉപയോഗം വർദ്ധിച്ചു. പിന്നീട് അത് നിലച്ചുപോയി. ഒരു എററും (error) വന്നില്ല. നിശബ്ദത മാത്രം.
ഒരു തകരാറിലായ ഷെഡ്യൂളർ (scheduler) ഡിബഗ് ചെയ്യാൻ ഞാൻ മണിക്കൂറുകൾ പാഴാക്കി. ഞാൻ തെറ്റാണ് ചെയ്തത്. ചാനലുകൾ എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നതെന്ന് എനിക്ക് മനസ്സിലായില്ല.
നിങ്ങളുടെ Go പ്രോഗ്രാമുകൾ ഹാങ്ങ് ആകാതിരിക്കാൻ മൂന്ന് നിയമങ്ങൾ ഇതാ.
- Nil ചാനലുകൾ ബ്ലാക്ക് ഹോളുകളാണ് ഒരു nil ചാനൽ എന്നെന്നേക്കുമായി ബ്ലോക്ക് ചെയ്യും. ഒരു nil ചാനലിൽ നിങ്ങൾ ഡാറ്റ അയക്കുകയോ സ്വീകരിക്കുകയോ ചെയ്താൽ, ആ goroutine കുടുങ്ങിപ്പോകും.
- എപ്പോഴും
makeഉപയോഗിച്ച് നിങ്ങളുടെ ചാനലുകൾ ഇൻസ്റ്റാഷ്യലൈസ് (initialize) ചെയ്യുക. - നിങ്ങൾക്ക് ഉറപ്പില്ലെങ്കിൽ ഒരു nil ചെക്ക് ഉപയോഗിക്കുക.
- ക്ലോസിംഗ് നിയമങ്ങൾ പാണിക്സ് (panics) ഒഴിവാക്കുന്നു ഒരു ചാനൽ ക്ലോസ് ചെയ്യുന്നത് ശാശ്വതമാണ്.
- അയക്കുന്നയാൾ (sender) മാത്രമേ ഒരു ചാനൽ ക്ലോസ് ചെയ്യാൻ പാടുള്ളൂ.
- ക്ലോസ് ചെയ്ത ഒരു ചാനലിലേക്ക് ഡാറ്റ അയക്കുന്നത് പാണിക് (panic) ഉണ്ടാക്കും.
- ഒരു ചാനൽ ക്ലോസ് ചെയ്തോ എന്ന് പരിശോധിക്കാൻ രണ്ടാമത്തെ റിട്ടേൺ വാല്യൂ ഉപയോഗിക്കുക:
v, ok := <-ch. okഎന്നത്falseആണെങ്കിൽ, ചാനൽ ക്ലോസ് ചെയ്യപ്പെട്ടതാണ്.
- സുരക്ഷയ്ക്കായി ചാനൽ ദിശകൾ (channel directions) ഉപയോഗിക്കുക ഒരു ചാനൽ ഡാറ്റ അയക്കാനാണോ അതോ സ്വീകരിക്കാനാണോ എന്ന് നിശ്ചയിക്കാൻ Go നിങ്ങളെ അനുവദിക്കുന്നു.
chan<- intഎന്നാൽ നിങ്ങൾക്ക് ഡാറ്റ അയക്കാൻ മാത്രമേ കഴിയൂ എന്നാണ് അർത്ഥം.<-chan intഎന്നാൽ നിങ്ങൾക്ക് ഡാറ്റ സ്വീകരിക്കാൻ മാത്രമേ കഴിയൂ എന്നാണ് അർത്ഥം.- ഇത് കോഡ് റൺ ചെയ്യുന്നതിന് മുമ്പ് തന്നെ തെറ്റുകൾ കണ്ടെത്താൻ കമ്പൈലറെ (compiler) സഹായിക്കുന്നു.
എങ്ങനെ ഒരു ക്ലീൻ പൈപ്പ്ലൈൻ നിർമ്മിക്കാം:
- ഒരു ചാനൽ കൃത്യമായി ഒരു തവണ മാത്രം ക്ലോസ് ആകുന്നുണ്ടെന്ന് ഉറപ്പാക്കാൻ
defer closeഉപയോഗിക്കുക. - ചാനലുകളിൽ ലൂപ്പ് ചെയ്യാൻ
rangeഉപയോഗിക്കുക. ചാനൽ ക്ലോസ് ചെയ്യപ്പെടുമ്പോൾ ഇത് തനിയെ നിൽക്കും. - കർശനമായ നിയമങ്ങൾ (strict contracts) ഉണ്ടാക്കുന്നതിനായി നിങ്ങളുടെ ഫംഗ്ഷനുകൾക്ക് ഡയറക്ഷൻ ടൈപ്പുകൾ (direction types) നൽകുക.
ഈ രീതികൾ പിന്തുടരുമ്പോൾ, നിങ്ങൾക്ക് മെമ്മറി ലീക്കുകളും (leaks) പാണിക്സും ഒഴിവാക്കാം. പരിശോധിക്കാൻ എളുപ്പമുള്ളതും കരുത്തുറ്റതുമായ സിസ്റ്റങ്ങൾ നിങ്ങൾക്ക് നിർമ്മിക്കാം.
നിങ്ങളുടെ വെല്ലുവിളി:
ഒന്നിലധികം ഇൻപുട്ട് ചാനലുകളെ ഒരു ഔട്ട്പുട്ട് ചാനലിലേക്ക് ലയിപ്പിക്കുന്ന (merge) ഒരു ഫംഗ്ഷൻ എഴുതുക. ഒരു select ലൂപ്പ് ഉപയോഗിക്കുക. 500ms ടൈമൗട്ട് (timeout) ചേർക്കുക. ഒരു goroutine പോലും ലീക്ക് (leak) ആകുന്നില്ലെന്ന് ഉറപ്പാക്കുക.
നിങ്ങളുടെ പരിഹാരം കമന്റുകളിൽ പോസ്റ്റ് ചെയ്യുക.