𝗚𝗼 𝗖𝗼𝗻𝘁𝗲𝘅𝘁 𝗣𝗮𝗰𝗸𝗮𝗴𝗲
മിക്ക Go ഡെവലപ്പർമാരും context.Context എന്താണെന്ന് കൃത്യമായി മനസ്സിലാക്കാതെയാണ് അത് ഉപയോഗിക്കുന്നത്. HTTP ഹാൻഡ്ലറുകളിലും (handlers), ഡാറ്റാബേസ് കോളുകളിലും (database calls), SDK മെത്തേഡുകളിലും നിങ്ങൾ ഇത് കാണാറുണ്ട്. പല തുടക്കക്കാരും എല്ലായിടത്തും context.Background() ആണ് പാസ്സ് ചെയ്യുന്നത്.
ഈ തെറ്റ് പല പ്രശ്നങ്ങൾക്കും കാരണമാകും. ഒരു Lambda ഫംഗ്ഷൻ അതിന്റെ ടൈമൗട്ടിന് (timeout) ശേഷവും പ്രവർത്തിച്ചുകൊണ്ടിരിക്കാം. ഒരു യൂസർ ഡിസ്കണക്റ്റ് ആയതിന് ശേഷവും ഒരു ഡാറ്റാബേസ് ക്വറി (database query) പ്രവർത്തിച്ചുകൊണ്ടിരിക്കാം.
കോഡിലൂടെ ക്യാൻസലേഷൻ സിഗ്നലുകളും (cancellation signals) ഡെഡ്ലൈനുകളും (deadlines) അയക്കാൻ Context നിങ്ങളെ അനുവദിക്കുന്നു. ഇത് താഴെ പറയുന്ന മൂന്ന് ചോദ്യങ്ങൾക്ക് ഉത്തരം നൽകാൻ നിങ്ങളെ സഹായിക്കുന്നു:
• ഈ ഓപ്പറേഷൻ തുടർന്നും പ്രവർത്തിക്കണോ? • ഈ ഓപ്പറേഷൻ എപ്പോൾ അവസാനിക്കണം? • ഈ കോളിനൊപ്പം ഏത് റിക്വസ്റ്റ് ഡാറ്റയാണ് ഒഴുകുന്നത്?
Context ഇന്റർഫേസിൽ (interface) നാല് മെത്തേഡുകൾ ഉണ്ട്:
- Deadline(): കോൺടെക്സ്റ്റ് എപ്പോൾ ക്യാൻസൽ ചെയ്യുമെന്ന് ഇത് തിരികെ നൽകുന്നു.
- Done(): കോൺടെക്സ്റ്റ് ക്യാൻസൽ ചെയ്യുമ്പോൾ ക്ലോസ് ചെയ്യുന്ന ഒരു ചാനൽ (channel) ഇത് നൽകുന്നു. ജോലി നിർത്തുന്നതിനായി select സ്റ്റേറ്റ്മെന്റുകളിൽ ഇത് ഉപയോഗിക്കുക.
- Err(): കോൺടെക്സ്റ്റ് എന്തുകൊണ്ട് നിർത്തപ്പെട്ടു എന്ന് ഇത് തിരികെ നൽകുന്നു (DeadlineExceeded അല്ലെങ്കിൽ Canceled).
- Value(): Trace ID പോലുള്ള റിക്വസ്റ്റ് സ്കോപ്പ് ഡാറ്റ (request-scoped data) ഇത് വീണ്ടെടുക്കുന്നു.
Context ഒരു മരം (tree) പോലെയാണ് പ്രവർത്തിക്കുന്നത്. നിങ്ങൾ ഒരു പാരന്റ് കോൺടെക്സ്റ്റിൽ (parent context) നിന്ന് തുടങ്ങി ചൈൽഡ് കോൺടെക്സ്റ്റുകൾ (children) നിർമ്മിക്കുന്നു.
Root Contexts:
- context.Background(): നിങ്ങളുടെ പ്രോഗ്രാമിന്റെ തുടക്കത്തിൽ ഇത് ഉപയോഗിക്കുക.
- context.TODO(): റീഫാക്റ്ററിംഗിനിടെ (refactoring) ഒരു പ്ലേസ്ഹോൾഡറായി ഇത് ഉപയോഗിക്കുക.
Child Contexts:
- context.WithCancel(): ജോലി മാനുവലായി നിർത്താൻ ഇത് അനുവദിക്കുന്നു.
- context.WithTimeout(): ഒരു നിശ്ചിത സമയത്തിന് ശേഷം ജോലി നിർത്തുന്നു.
- context.WithDeadline(): ഒരു നിശ്ചിത സമയത്ത് ജോലി നിർത്തുന്നു.
- context.WithValue(): User ID പോലുള്ള മെറ്റാഡാറ്റകൾ (metadata) പാസ്സ് ചെയ്യുന്നു.
നിർണ്ണായകമായ നിയമം: എപ്പോഴും cancel ഫംഗ്ഷൻ വിളിക്കുക. ഒരു ചൈൽഡ് കോൺടെക്സ്റ്റ് നിർമ്മിച്ച ഉടൻ തന്നെ defer cancel() ഉപയോഗിക്കുക. നിങ്ങൾ ഇത് ഒഴിവാക്കിയാൽ, അത് മെമ്മറി ലീക്കുകൾക്ക് (memory leaks) കാരണമാകും.
Best Practices:
- ഫംഗ്ഷനുകളിലേക്ക് ആദ്യത്തെ ആർഗ്യുമെന്റായി (argument) context പാസ്സ് ചെയ്യുക.
- കോൺടെക്സ്റ്റുകൾ സ്ട്രക്റ്റുകളിൽ (structs) സൂക്ഷിക്കരുത്.
- context.WithValue മെറ്റാഡാറ്റയ്ക്ക് വേണ്ടി മാത്രം ഉപയോഗിക്കുക, ഡാറ്റാബേസ് ക്ലയന്റുകൾ പോലുള്ള ഡിപെൻഡൻസികൾക്കായി (dependencies) ഉപയോഗിക്കരുത്.
- നേരത്തെ പുറത്തുകടക്കുന്നതിനായി നീളമുള്ള ലൂപ്പുകൾക്കുള്ളിൽ (loops) ctx.Err() പരിശോധിക്കുക.
- കോളിഷനുകൾ (collisions) ഒഴിവാക്കാൻ കോൺടെക്സ്റ്റ് കീകൾക്കായി (context keys) കസ്റ്റം ടൈപ്പുകൾ ഉപയോഗിക്കുക.
ഒരു പാരന്റ് കോൺടെക്സ്റ്റ് ക്യാൻസൽ ചെയ്യുമ്പോൾ, അതിന്റെ എല്ലാ ചൈൽഡ് കോൺടെക്സ്റ്റുകളും സ്വയമേവ ക്യാൻസൽ ചെയ്യപ്പെടും. ഇത് നിങ്ങളുടെ സിസ്റ്റത്തിലുടനീളമുള്ള ഓപ്പറേഷനുകളുടെ ഒരു ശൃംഖല തന്നെ എളുപ്പത്തിൽ നിർത്താൻ സഹായിക്കുന്നു.