CloudyGo
212 subscribers
8 photos
1 video
1 file
41 links
Software Engineering & Development Best Practices, Especially in Golang!


https://cloudygo.ir

@rezakhademix
Download Telegram
#گولنگ

یکی از توصیه‌های کاربردی و مهم در تابع main برنامه‌های گولنگی اینه که بهتره نهایتا یک‌بار از log.Fatal یا os.Exit استفاده کنیم.

یعنی اگر ما در تابع main بخش‌های کلیدی و وابستگی‌های برنامه مثل دیتابیس و... رو آماده و برای چک کردن هر بخش بارها از log.Fatal استفاده کنیم، به‌طور فزاینده و غیرضروری تابع main رو طولانی‌ کردیم و حتی گاها رفتار عجیبی از یک قسمت سر میزنه که مورد انتظار ما نیست.

کد معمولی:

package main

func main() {
args := os.Args[1:]
if len(args) != 1 {
log.Fatal("file is missing")
}
name := args[0]

f, err := os.Open(name)
if err != nil {
log.Fatal(err)
}
defer f.Close()

// If we call log.Fatal after this line,
// f.Close will not be called.

b, err := io.ReadAll(f)
if err != nil {
log.Fatal(err)
}

db, err := db.New()
if err != nil {
log.Fatal(err)
}
defer db.Close()

// Again, if we call log.Fatal after
// this line, db.Close will not be called.

// ...
}

کد بهتر:

package main

func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}

func run() error {
args := os.Args[1:]
if len(args) != 1 {
return errors.New("file is missing")
}
name := args[0]

f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()

b, err := io.ReadAll(f)
if err != nil {
return err
}

db, err := db.New()
if err != nil {
return err
}
defer db.close()

// ...
}

#golang
#tip
👍1
Indexing Beyond the Basics -- Tobias Petry -- 2023.pdf
11.4 MB
Indexing Beyond The Basics - Book

این کتاب دید شفافی در رابطه با نحوه ایندکس گذاری‌ها در دیتابیس و اینکه‌ چطور استفاده بهتری از ایندکس‌ها داشته باشیم به ما میده.

#book
👍1
شاید براتون جالب باشه که وب‌سایت‌هایی مثل توییتر چطور دائما فید کاربر رو به‌روز می‌کنن؟
یا چطور میشه خیلی سبک و بدون رکوئست‌های متعدد برای کاربر نوتیفیکیشن ارسال کرد؟

اگر راهکارتون استفاده از websocket هست، کمی درست گفتین اما وب‌سوکت علاوه‌بر چالش‌هایی که داره، در حقیقت یک کانکشن دوطرفه باز می‌کنه که به کلاینت و سرور اجازه میده هردو اطلاعات مورد نظرشون رو ارسال کنن.
یک بار دیگه برگردیم از اول، وقتی به رکوئست‌های توییتر نگاه کنین، آیا کانکشن وب‌سوکت می‌بینین؟ خیر، ارتباط وب‌سوکت وجود نداره، پس چطور ممکنه؟

راه‌حل در چنین مواری استفاده از SSE هستش. در واقع Server-Sent Events برای شما یک کانکشن realtime یک طرفه از سرور به کلاینت ایجاد می‌کنه که روی HTTP هستش، این کانکشن overhead کمتری داره و به هر مدت زمانی‌که سرور مشخص میکنه باز میمونه و اطلاعات رو به کلاینت میفرسته.

ویژگی‌ها:
۱. سادگی پیاده‌سازی
۲. مرورگرها از این ارتباط پشتیبانی میکنن
۳. اتصال مجدد خودکار در صورت قطع شدن کانکشن
۴. کاهش overhead و استفاده از یک کانکشن



#tip
نمونه کد اجرای یک کانکشن SSE در گولنگ:


import (
"fmt"
"net/http"
"time"
)

func sseHandler(w http.ResponseWriter, r *http.Request) {
// set SSE http headers
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")

// create a channel for client disconnection
clientIsGone := r.Context().Done()

rc := http.NewResponseController(w)

t := time.NewTicker(time.Second)
defer t.Stop()

for {
select {
case <-clientIsGone:
fmt.Println("client disconnected")
return

case <-t.C:
// send event to the client
_, err := fmt.Fprintf(w, "data: the time is %s\n\n", time.Now().Format(time.UnixDate))
if err != nil {
return
}

err = rc.Flush()
if err != nil {
return
}
}
}
}


#tip
#golang
داکرایز کردن الستیک 🫎 نکات ریز خودش رو داره اما ریپازیتوری docker elk میتونه در این پروسه کمک‌تون کنه تا راحت‌تر به هدف‌تون برسید.


#docker
#elk
👍1
این مقاله دید جالبی درباره استفاده از ORM داره وخوندنش خالی از لطف نیست.


#tip
#blog
👏1🤔1
دائما به فکر راه‌حل‌های پیچیده نباشید!

جامپ زدن بین مراحل و اینکه فکر کنید استفاده از یک سرویس بزرگ، خیال شما رو راحت میکنه و دیگه نیازی نیست تا مدتها به اون قسمت دست بزنید، کاملا نتیجه برعکس میده و دردسرهایی به وجود میاره که قابل وصف نیست!


#tip
#blog
👍3
این مقاله دید جالبی در رابطه با دیپلوی کردن سرویس‌های داکری مطرح میکنه و دوباره موضوع مهم تگ زدن رو برامون یادآوری می‌کنه تا راحت‌تر بتونیم رول‌بک و از مشکلات احتمالی جلوگیری کنیم

#blog
👏2👍1
#فان

یه مایگریشن نوشتم، ۱۱۵ خط شده، به نظرم خیلی عالیه! :)
1😱1
#blog

شما با postgresql میتونید لاگ تغییرات جدول‌ها رو داشته باشید و به ‌صورت خودکار تمام تغییرات رو لاگ کنید. البته برای سیستم‌های زیر بار یا اینترپرایز پیشنهاد نمیشه و راه‌حل‌های بهتری هست اما این مقاله رو به این خاطر بخونید که بیشتر با postgresql و قابلیت‌هاش آشنا بشید.


https://www.cybertec-postgresql.com/en/tracking-changes-in-postgresql/
2
#blog
#tip

نحوه نوشتن کدها در گولنگ یا همان code style guide یکی از بحث‌های مهم هستش که گاها بهش کم توجه میشه.

اینکه شما باید متغیرها رو در نزدیک جایی که مورد استفاده قرار میگیرن، تعریف کنید یا شروع کردن لاگ یا پرینت با حروف بزرگ یک bad practice محسوب میشه.

‍‍‍‍‍
fmt.Sprintf("Here is a bad practice: %s", "don't do this")

fmt.Sprintf("here is a good practice: %s", "do this!")

این مقاله لیست کل قانون‌‌هایی که خود گوگل برای بهتر و خواناتر نوشتن گولنگ منتشر کرده و خوندنش خالی از لطف نیست.

https://google.github.io/styleguide/go/best-practices
👍3👏1
#blog
#tip

این مقاله از techblog تیندر در مورد نحوه طراحی API‌های خودشون صحبت می‌کنه و سناریوهایی رو میگه که هممون تجربه کردیم. مثلا همیشه میدونیم واکشی اطلاعات با متد GET انجام میشه اما در برخی اوقات نیاز داریم از متد POST استفاده کنیم. اگه وقت کردین بخونیدش نکات ریز جالبی داره و خالی از لطف نیست.

https://medium.com/tinder/tinder-api-style-guide-part-1-081804a7ef40
2👏1
#golang
#tip

مشکل کد زیر کجاست؟

‍‍‍
func main() {

names := make([]string, 0, 10)

names[0] = "reza"

fmt.Println(names)
}

خب این برنامه در ظاهر مشکلی نداره، یک اسلایس تعریف و در خط بعدی ایندکس صفرم دارای مقدار شده، اما نکته مهم اینجاست برای متغیر names یک اسلایس با ظرفیت (capacity) 10، اما طول (length) حقیقی صفر ایجاد شده و هنگامی ‌که در خط بعدی تصمیم به مقداردهی یکی از ایندکس‌های اسلایس می‌کنیم برنامه با خطای ران‌تایم مواجه میشه و نتیجه چنین کدی مساوی با خطای زیر است:

‍‍‍
panic: runtime error: index out of range [0]  with length 0


اگر می‌خواهید به اسلایسی که طول آن صفر است مقداری را اضافه کنید باید با استفاده از تابع ()append به شکل زیر این کار را انجام دهید.

names = append(names, "reza")


اما اگر نیاز داریم حتما مقادیر در ایندکس‌های مشخص در این اسلایس قرار بگیرند باید تعریف متغیر names را به‌ روش درست زیر انجام دهیم:

 names := make([]string, 10)


در این نوع تعریف علاوه‌بر تعیین ظرفیت، طول حقیقی اسلایس نیز معین میشه تا از خطای ران‌تایم جلوگیری شود.
دقت کنید تعریف اسلایس با کلمه کلیدی var و تکرار روند بالا بازهم برنامه را با خطای index out of range روبرو خواهد کرد.

var ages []int
ages[1] = 29 // this line will fail with runtime error: index out of range [1] with length 0



#tip
#golang
1🔥1😱1
#event

سلام دوستان
در نظر دارم تا اولین وبینار خصوصی برنامه‌نویسی cloudygo رو با موضوع «انقلاب در حوزه بک‌اند» برگزار کنم.

طبیعتا این رویداد رایگان، به‌صورت آنلاین و در بستر گوگل‌میت خواهد بود.

حد نصاب علاقمندان برای برگزاری ۷ نفر و حداکثر نفرات ۱۵ نفر خواهد بود که مسلما در آینده نفرات این وبینار از قابلیت‌های پریمیوم کانال cloudygo به‌صورت رایگان بهره‌مند خواهند شد. (این پیام را برای دوستان برنامه‌نویس علاقمند خود ارسال کنید)

خواهشمندم در نظرسنجی زیر شرکت کنید تا بهتر بتونیم رویداد رو برگزار یا موقتا کنسل کنیم.

طبیعتا برای اینکه مسیر آموزش‌های آینده هموار بشه همه ما باید با یک سری مفاهیم آشنا بشیم تا در زمان درست به یادگیری عمیق بپردازیم.

هدف از این وبینار شروع آشنایی و شرح موضوع درباره مباحث فنی زیر خواهد بود و مختص به یک زبان خاص نیست:

۰. توسعه با زبان گولنگ چرا و‌ چگونه؟
۱. پروژه‌های بک‌اند، گیت و دیپلوی سنتی
۲. ریپازیتوری، داکر، پادمن، ریجیستری، کوبرنتیز
۳. دیپلوی و ci cd
۴. مقیاس‌پذیری چیست و چرا مهم است؟
۵. چطور بدانیم مشکل از کجاست؟
۶. ابزارهای کاربردی برای مدیریت بهتر


هدف من بعد از این وبینار، برگزاری جلسات آینده همراه با خروجی مؤثر و اجرای تک‌تک قسمت‌ها در یک پروژه واقعی Golang خواهد بود.
👏2👍1
در اولین وبینار خصوصی cloudygoشرکت می‌کنید؟ (زمان برگزاری ‌به‌زودی اعلام خواهد شد)
Final Results
80%
بلی
20%
خیر
2
#رویداد
#cloudygo

سلام
از همراهی همه شما بسیار ممنونم، این هفته بسیار سرم شلوغ بود!

رویداد Backend Evolution به همت شما، برگزار خواهد شد و در حال آماده‌سازی سرفصل‌ها هستم.

امروز بالاخره تونستم یک ساعت وقت بذارم و سایت کامیونیتی رو ایجاد کنم.

https://cloudygo.ir

سایت در آینده بخش‌های مختلفی رو شامل خواهد شد و هدف من برگزاری رویدادهای live coding برای آموزش موضوعات مختلف از جمله:
Golang, CI/CD, Docker, Microservices, Kubernetes, Open Telemetry, ...

خواهد بود.

به زودی سرفصل رویداد و زمان برگزاری رو در اختیار شما خواهم گذاشت.

از امشب ثبت نام برای علاقمندان از طریق سایت امکان پذیر است.
👍2👏2
#رویداد

اولین وبینار کلودی‌گو با عنوان «تحول بک‌اند» برگزار خواهد شد.

سرفصل‌های این وبینار به‌صورت زیر خواهد بود:

۰. پروژه‌های بک‌اند، گیت و دیپلوی سنتی

۱. داکر، پادمن، کوبرنتیز
- بررسی داکر، پادمن، آموزش کانتینر کردن اپلیکیشن و یادگیری نحوه عملکرد کوبرنتیز

۲. میکروسرویس‌ها و CI CD
- بررسی ماهیت میکروسرویس‌ها و مقیاس‌پذیری، آموزش راه‌اندازی یک سرویس CI CD و دیپلوی خودکار

۳. گرفانا، پرمتئوس
- آموزش راه‌اندازی سرویس گرفانا و پرومتئوس برای مانیتورینگ سرویس‌های مختلف

۴. گولنگ
- چرا توسعه با زبان گولنگ را یاد بگیریم؟
- مسیر آینده کلودی‌گو برای آموزش برنامه‌نویسی گولنگ با clean arch، میکروسرویس، کوبرنتیز


🗓 زمان برگزاری:
پنجشنبه ۱۰ آبان ۱۴۰۳
ساعت ۱۶:۰۰
پلتفرم: گوگل‌میت

📝 ثبت‌نام:
https://cloudygo.ir
🔥21
#رویداد

فردا پنجشنبه ۱۰ آبان ۱۴۰۳ ساعت ۱۶:۰۰ رویداد Backend Evolution کلودی‌گو برگزار خواهد شد و عزیزانی که ثبت‌نام کرده‌اند، لینک شرکت در رویداد براشون ارسال شده است.
ثبت‌نام در رویداد از دیشب به ‌پایان رسیده و امیدارم در رویدادهای بعدی همراه ما باشید.

توضیحات:
با عرض پوزش، به‌دلیل تداخل تایم‌زون سرور، ساعت رویداد در ایمیل یادآوری به‌درستی تنظیم نشده بود!

🗓 زمان برگزاری:
پنجشنبه ۱۰ آبان ۱۴۰۳
ساعت ۱۶:۰۰
پلتفرم: گوگل‌میت


#cloudygo
#event
🔥2👏21
یک راهنمای خوب در خصوص نحوه افزایش Observability و Tracing
در برنامه‌های گولنگ با بررسی بررسی مموری، گوروتین‌ها، تردها و...

https://github.com/DataDog/go-profiler-notes/blob/main/guide/README.md

#blog
#tip
👍5
#رویداد

فایل ارائه، تمامی کدها و بخش‌هایی که در وبینار Backend Evolution در موردش صحبت و ایجاد کردیم به تفکیک در ریپازیتوری زیر قرار گرفت. در هر قسمت می‌توانید با خواندن فایل readme از اطلاعات مورد نیاز برای استفاده از کدها مطلع شوید.

https://github.com/rezakhademix/cloudygo
👍6🙏2