బెంచ్మార్క్ ఉచ్చు (The Benchmark Trap)
బెంచ్మార్క్ పోస్టర్లు మీకు ఎప్పుడూ పూర్తి చిత్రాన్ని చూపించరు. అవి దాదాపు ఏమీ చేయని ఒక హ్యాండ్లర్ను మాత్రమే కొలుస్తాయి. ఒక JSON Hello World లేదా ఒక స్టాటిక్ స్ట్రింగ్ వంటివి. ఆ శూన్యంలో (vacuum), Fiber స్పష్టంగా విజయం సాధిస్తుంది. అది Gin కంటే సెకనుకు ఎక్కువ రిక్వెస్ట్లను అందిస్తుంది మరియు తక్కువ మెమరీని వినియోగిస్తుంది. అది నిజమైన ఇంజనీరింగ్. కానీ మీ అప్లికేషన్ అనేది ఒక శూన్యం కాదు.
నేను కెన్యాలో ఒక రియల్-టైమ్ సెక్యూరిటీ యాప్ను రూపొందిస్తున్నాను. ఇది నైరోబీ మరియు మోంబాసా అంతటా ఉన్న వినియోగదారుల నుండి GPS కోఆర్డినేట్లను తీసుకుంటుంది మరియు నేర ప్రాంతాలు లేదా రోడ్డు ప్రమాదాల గురించి హెచ్చరికలను పంపిస్తుంది. అంటే PostgreSQL రైట్స్, Firebase Cloud Messaging కాల్స్ మరియు రివర్స్ జియోకోడింగ్ లుకప్లు జరుగుతాయి. మీ స్టాక్లో నెట్వర్క్ హాప్స్ మరియు డేటాబేస్ రౌండ్-ట్రిప్స్ ఉన్నప్పుడు, రూటింగ్ కోసం నానో సెకన్లను ఆదా చేసే ఫ్రేమ్వర్క్ ఏమాత్రం కనిపించదు. బాటిల్నెక్ (bottleneck) ఎప్పుడూ రూటర్ కాదు. అది SMS గేట్వే టైమ్ అవుట్ అవ్వడం కావచ్చు. లేదా ఇన్సిడెంట్ రిపోర్ట్ల టేబుల్ను స్కాన్ చేసే PostGIS క్వెరీ కావచ్చు. ప్రాడక్షన్ను ఎదుర్కొనే వరకు రా (raw) త్రూపుట్ (throughput) ఆకర్షణీయంగా కనిపిస్తుంది.
స్టాండర్డ్ లైబ్రరీ పట్ల విధేయత (Standard Library Loyalty)
Gin నేరుగా net/http పై నిర్మించబడింది. ఇది వినబడే దానికంటే ఎక్కువ ప్రాముఖ్యత కలిగి ఉంటుంది.
ప్రతి Go డెవలపర్కు net/http తెలుసు. డీబగ్గింగ్ చేసేటప్పుడు తెలిసిన స్టాక్ ట్రేస్లు (stack traces) వస్తాయి. ఐదేళ్ల క్రితం రాసిన మిడిల్వేర్ కూడా ఎటువంటి ఇబ్బంది లేకుండా నేరుగా ఉపయోగించవచ్చు. రిక్వెస్ట్ మరియు రెస్పాన్స్ ఆబ్జెక్ట్లు Go డాక్యుమెంటేషన్లో చెప్పినట్లే పనిచేస్తాయి. Gin భాషకు దగ్గరగా ఉండటం వల్ల అది ఊహించదగినదిగా (predictable) ఉంటుంది.
Fiber ఆ పునాదిని fasthttpతో భర్తీ చేస్తుంది, ఇది zero-allocation పెర్ఫార్మెన్స్ కోసం ఆప్టిమైజ్ చేయబడిన ఒక కస్టమ్ HTTP ఇంజిన్. దానిని సాధించడానికి, ఇది Request/Response Poolingని ఉపయోగిస్తుంది. ప్రతి రిక్వెస్ట్ తర్వాత గార్బేజ్ కలెక్టర్ మెమరీని తిరిగి తీసుకోవడానికి అనుమతించే బదులు, Fiber మెమరీ బ్లాక్లను రీసైకిల్ చేస్తుంది. ఇది వాటిని క్లీన్ చేసి తదుపరి వచ్చే కనెక్షన్కు అందిస్తుంది. ఆ ట్రిక్ వల్లనే వేగం వస్తుంది. అదే ప్రమాదానికి కూడా కారణం.
పునర్వినియోగ మెమరీలోని దాగి ఉన్న ప్రమాదం (The Hidden Danger of Reused Memory)
సిద్ధాంతపరంగా Pooling సురక్షితంగా అనిపిస్తుంది. కానీ ఆచరణలో, ఇది ఒక సూక్ష్మమైన నిబంధనను విధిస్తుంది: మీ హ్యాండ్లర్ పూర్తయిన తర్వాత మీరు రిక్వెస్ట్ డేటా యొక్క రిఫరెన్స్ను ఎప్పుడూ ఉంచుకోకూడదు. ఒకవేళ ఒక goroutine రిక్వెస్ట్ కంటే ఎక్కువ కాలం కొనసాగినా, లేదా మీరు తదుపరి ప్రాసెసింగ్ కోసం రిక్వెస్ట్ బాడీ యొక్క స్లైస్ను (slice) తీసుకున్నా, Fiber ఆ మెమరీని తిరిగి తీసుకుని తదుపరి వినియోగదారునికి అందిస్తుంది.
దీని ఫలితం కంటామినేషన్ (contamination). ఈ బగ్ యూనిట్ టెస్ట్లో కనిపించదు. నైరోబీలోని డ్రైవర్ యొక్క GPS కోఆర్డినేట్ అకస్మాత్తుగా కిసుములోని మ్యాప్లో కనిపించడం వంటివి జరుగుతాయి. ఒక వినియోగదారుని JWT టోకెన్ మరొక వినియోగదారుని కాంటెక్స్ట్లోకి లీక్ అవ్వడం వంటివి జరుగుతాయి. ఇవి తాత్కాలిక వైఫల్యాలు (temporal failures). మీరు లాగింగ్ (logging) జోడించినప్పుడు ఇవి మాయమవుతాయి, ఎందుకంటే లాగింగ్ చేయడం వల్ల కొత్త మెమరీ కేటాయించబడుతుంది మరియు టైమింగ్ మారుతుంది. దీనివల్ల మీరు దెయ్యాలను వెంటాడినట్లు (chasing ghosts) అవుతుంది.
Ginతో, స్టాండర్డ్ లైబ్రరీ ఒక కొత్త రిక్వెస్ట్ ఆబ్జెక్ట్ను కేటాయిస్తుంది. అక్కడ విషపూరితం (poison) చేయడానికి ఎలాంటి పూల్ ఉండదు. మీ అప్లికేషన్ నిజమైన భద్రతతో ముడిపడి ఉన్న నిజమైన లొకేషన్లను హ్యాండిల్ చేస్తున్నప్పుడు ఆ భద్రత చాలా ముఖ్యం.
ఎకోసిస్టమ్ గ్రావిటీ (Ecosystem Gravity)
కంపాటబిలిటీ (compatibility) విషయంలో కూడా ఒక నిశ్శబ్ద పన్ను (tax) ఉంటుంది.
చాలా Go మిడిల్వేర్లు net/httpని అనుసరిస్తాయి. JWT వాలిడేటర్లు, OpenTelemetry ఎక్స్పోర్టర్లు, CORS హ్యాండ్లర్లు మరియు రేట్ లిమిటర్లు అన్నీ స్టాండర్డ్ ఇంటర్ఫేస్ను ఉపయోగిస్తాయి. Gin ఆ ఇంటర్ఫేస్ను నేరుగా అర్థం చేసుకుంటుంది. ఏదైనా మిడిల్వేర్ను జోడిస్తే అది పనిచేస్తుంది.
Fiberకు దాని స్వంత కాంటెక్స్ట్ టైప్ మరియు హ్యాండ్లర్ సిగ్నేచర్ ఉంటాయి. మీకు అడాప్టర్లు (adapters) అవసరం అవుతాయి. కొన్నిసార్లు అడాప్టర్ అధికారికంగా ఉంటుంది. కొన్నిసార్లు అది అప్స్ట్రీమ్ లైబ్రరీ కంటే ఏడాది వెనుకబడి ఉండవచ్చు. కొన్నిసార్లు లోడ్ ఉన్నప్పుడు అది కొంచెం భిన్నంగా ప్రవర్తించవచ్చు. మీరు ఒక చిన్న టీమ్ను నడుపుతున్నప్పుడు, ఒక అథెంటికేషన్ మిడిల్వేర్ మీ లాప్టాప్లో పనిచేసి, సర్వర్లో సరైన టోకెన్లను ఎందుకు తిరస్కరిస్తుందో డీబగ్ చేయడానికి మీకు అదనపు సమయం ఉండదు. go get అనేది బోరింగ్గా ఉండాలని మీరు కోరుకుంటారు. Gin దానిని బోరింగ్గా ఉంచుతుంది, తెల్లవారుజామున 3 గంటల సమయంలో మీకు కావాల్సింది కూడా అదే.
అప్లికేషన్కు నిజంగా ఏమి కావాలి (What the App Actually Needs)
నా సెక్యూరిటీ సర్వీస్ ఏకకాలంలో ఉన్న వినియోగదారుల నుండి ప్రతి కొన్ని సెకన్లకు ఒకసారి లొకేషన్ పింగ్లను ప్రాసెస్ చేస్తుంది. ఇది అధిక రిస్క్ ఉన్న రోడ్లకు జియోఫెన్సింగ్ (geofencing) చేస్తుంది. నోటిఫికేషన్లను ట్రిగ్గర్ చేస్తుంది. ఆలస్యమైన హెచ్చరిక నిరాశ కలిగిస్తుంది. తప్పుడు హెచ్చరిక ప్రమాదకరం. కరప్ట్ అయిన పూల్డ్ మెమరీ వల్ల ఎవరినైనా ప్రమాదం జరిగిన చోటు వైపు పంపడం అంగీకరించలేని విషయం.
ఇక్కడ త్రూపుట్ (throughput) కంటే విశ్వసనీయత (reliability) ముఖ్యం. నేను pprofని అటాచ్ చేసినప్పుడు అర్థమయ్యే స్టాక్ ట్రేస్లు నాకు కావాలి. కస్టమ్ మెమరీ పూల్ యొక్క అంతర్గత లైఫ్ సైకిల్ను అర్థం చేసుకోవాల్సిన అవసరం లేని మెమరీ ప్రొఫైల్స్ నాకు కావాలి. ఈ ప్రాజెక్ట్ను తదుపరి డెవలపర్ తీసుకున్నప్పుడు, fasthttp ఆబ్జెక్ట్ మోడల్ను నేర్చుకోకుండానే ఒక మధ్యాహ్నంలో పని ప్రారంభించగలగాలి. Gin నాకు అది ఇస్తుంది. ఆపరేషనల్ శానిటీ (Operational sanity) బెంచ్మార్క్లలో కనిపించదు, కానీ అది ఒక సర్వీస్ను నిలబెడుతుంది
