یکی از مهمترین مفاهیم در دنیای امروز داکر هستش.
اگر هنوز حوصله نکردین که شروع کنین و داکر رو یاد بگیرین یا شروع کردین ولی منبع درست و حسابی برای Best Practice داکر ندارین،
ریپازیتوری awesome docker یکی از بهترینهاست.
این ریپازیتوری برای درک سادهترین تا پیچیدهترین مطالب داکر مطالب مختلفی رو در اختیارتون میذاره.
#docker
#awesome
اگر هنوز حوصله نکردین که شروع کنین و داکر رو یاد بگیرین یا شروع کردین ولی منبع درست و حسابی برای Best Practice داکر ندارین،
ریپازیتوری awesome docker یکی از بهترینهاست.
این ریپازیتوری برای درک سادهترین تا پیچیدهترین مطالب داکر مطالب مختلفی رو در اختیارتون میذاره.
#docker
#awesome
GitHub
GitHub - veggiemonk/awesome-docker: :whale: A curated list of Docker resources and projects
:whale: A curated list of Docker resources and projects - veggiemonk/awesome-docker
❤1👍1
#گولنگ
اگر یک struct گولنگی تعریف کردین که داخلش از mutex استفاده میکنید، حتما باید متدهایی که روی این استراکت تعریف میشن بهصورت پوینتر باشن. اگر این موضوع فراموش بشه، یک نسخه کپی از mutex رو استفاده میکنید و در موقعیتهای همزمانی دچار مشکل میشین.
نمونه کد بد:
نمونه کد خوب:
#tip
#golang
اگر یک struct گولنگی تعریف کردین که داخلش از mutex استفاده میکنید، حتما باید متدهایی که روی این استراکت تعریف میشن بهصورت پوینتر باشن. اگر این موضوع فراموش بشه، یک نسخه کپی از mutex رو استفاده میکنید و در موقعیتهای همزمانی دچار مشکل میشین.
نمونه کد بد:
type User struct {
sync.Mutex
data map[string]string
}
func NewUser() User {
return User{
data: make(map[string]string),
}
}
func (m User) Get(k string) string {
m.Lock()
defer m.Unlock()
return m.data[k]
}نمونه کد خوب:
type User struct {
mu sync.Mutex
data map[string]string
}
func NewUser() *User {
return &User{
data: make(map[string]string),
}
}
func (m *User) Get(k string) string {
m.mu.Lock()
defer m.mu.Unlock()
return m.data[k]
}#tip
#golang
👍2🔥1
#گولنگ
معمولا گولنگ دولوپرها تفاوت و کاربرد اسلایسهای empty و nil رو باهم اشتباه میگیرن.
به کد زیر دقت کنید:
کافیه برای اسلایسهای بالا کد زیر رو اجرا کنید تا تفاوت nil و empty بودن رو متوجه بشین:
نتیجه میشه:
خب هرچهار مورد بهعنوان empty در نظر گرفته میشن یعنی اگر len اونارو بگیرین برابر با صفر میشه اما فقط دو مورد اول nil هستن.
دقت کنید:
۱) اسلایسهای nil در واقع empty هم هستن
۲) اسلایسهای nil در حافظه allocation ایجاد نمیکنن
۳) برای هردو نوع اسلایسهای nil و empty میتونیم از تابع append استفاده کنیم
خب پس کاربرد اسلایس nil چیه؟
فرض کنید تابعی دارین که داره یک یا چند اسلایس برمیگردونه، خب دیگه با گولنگ نیازی نیست که مثل زبانهای دیگه یک مقدار allocate شده برگردونید و با برگردوندن nil یا یک اسلایس nil حافظه کمتری مصرف میشه.
#golang
#tip
معمولا گولنگ دولوپرها تفاوت و کاربرد اسلایسهای empty و nil رو باهم اشتباه میگیرن.
به کد زیر دقت کنید:
// #1
var s []string
// #2
s = []string(nil)
// #3
s = []string{}
// #4
s = make([]string, 0)
کافیه برای اسلایسهای بالا کد زیر رو اجرا کنید تا تفاوت nil و empty بودن رو متوجه بشین:
// In Golang "\t" means tab character "\n" means new line
fmt.Printf("IsEmpty=%v \t IsNil=%v \n", len(s) == 0, s == nil)
نتیجه میشه:
#1
IsEmpty=true IsNil=true
#2
IsEmpty=true IsNil=true
#3
IsEmpty=true IsNil=false
#4
IsEmpty=true IsNil=false
خب هرچهار مورد بهعنوان empty در نظر گرفته میشن یعنی اگر len اونارو بگیرین برابر با صفر میشه اما فقط دو مورد اول nil هستن.
دقت کنید:
۱) اسلایسهای nil در واقع empty هم هستن
۲) اسلایسهای nil در حافظه allocation ایجاد نمیکنن
۳) برای هردو نوع اسلایسهای nil و empty میتونیم از تابع append استفاده کنیم
خب پس کاربرد اسلایس nil چیه؟
فرض کنید تابعی دارین که داره یک یا چند اسلایس برمیگردونه، خب دیگه با گولنگ نیازی نیست که مثل زبانهای دیگه یک مقدار allocate شده برگردونید و با برگردوندن nil یا یک اسلایس nil حافظه کمتری مصرف میشه.
func scores() []int {
s, err := apiCall();
if err != nil {
return nil
}
return s
}#golang
#tip
👏2
#گولنگ
وقتی گوروتینها (goroutine) رو استفاده میکنین باید همیشه مطمئن بشین که پروسه مورد نظرتون چه زمانی به پایان میرسه و در نتیجه اصطلاحا گوروتین خارج میشه.
گوروتینها در گولنگ توسط grabage collector پاکسازی نمیشن و با وجود سبک بودنشون هنوز هم میتونن باعث ایجاد مموری لیک (memory leak) در برنامهتون بشن یا برای همیشه در پسزمینه در حال اجرا باقی بمونن!
این رفتار در گولنگ اشتباه نیست و به برنامهنویس اجازه میده پروسسهای طولانی مدت رو به راحتی در حال اجرا نگهداره، مثلا ایجاد یک وبسرویس که خیلی راحت روی یک گوروتین بلاک شده توسط یک چنل در وضعیت اجرا باقی میمونه اما در بقیه موارد باید حواستون باشه که با نوشتن کد مناسب چرخه عمر گوروتینها رو به درستی کنترل کنید.
ابزارهای زیادی برای مشخص گوروتینهای لیکی وجود دارد. این مقاله در شرکت اوبر (Uber) دید جالبی در این زمینه داره و خوندنش خالی از لطف نیست.
#golang
#tip
وقتی گوروتینها (goroutine) رو استفاده میکنین باید همیشه مطمئن بشین که پروسه مورد نظرتون چه زمانی به پایان میرسه و در نتیجه اصطلاحا گوروتین خارج میشه.
گوروتینها در گولنگ توسط grabage collector پاکسازی نمیشن و با وجود سبک بودنشون هنوز هم میتونن باعث ایجاد مموری لیک (memory leak) در برنامهتون بشن یا برای همیشه در پسزمینه در حال اجرا باقی بمونن!
این رفتار در گولنگ اشتباه نیست و به برنامهنویس اجازه میده پروسسهای طولانی مدت رو به راحتی در حال اجرا نگهداره، مثلا ایجاد یک وبسرویس که خیلی راحت روی یک گوروتین بلاک شده توسط یک چنل در وضعیت اجرا باقی میمونه اما در بقیه موارد باید حواستون باشه که با نوشتن کد مناسب چرخه عمر گوروتینها رو به درستی کنترل کنید.
ابزارهای زیادی برای مشخص گوروتینهای لیکی وجود دارد. این مقاله در شرکت اوبر (Uber) دید جالبی در این زمینه داره و خوندنش خالی از لطف نیست.
#golang
#tip
👍2
#گولنگ
یکی از توصیههای کاربردی و مهم در تابع main برنامههای گولنگی اینه که بهتره نهایتا یکبار از log.Fatal یا os.Exit استفاده کنیم.
یعنی اگر ما در تابع main بخشهای کلیدی و وابستگیهای برنامه مثل دیتابیس و... رو آماده و برای چک کردن هر بخش بارها از log.Fatal استفاده کنیم، بهطور فزاینده و غیرضروری تابع main رو طولانی کردیم و حتی گاها رفتار عجیبی از یک قسمت سر میزنه که مورد انتظار ما نیست.
کد معمولی:
کد بهتر:
#golang
#tip
یکی از توصیههای کاربردی و مهم در تابع 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
این کتاب دید شفافی در رابطه با نحوه ایندکس گذاریها در دیتابیس و اینکه چطور استفاده بهتری از ایندکسها داشته باشیم به ما میده.
#book
👍1
شاید براتون جالب باشه که وبسایتهایی مثل توییتر چطور دائما فید کاربر رو بهروز میکنن؟
یا چطور میشه خیلی سبک و بدون رکوئستهای متعدد برای کاربر نوتیفیکیشن ارسال کرد؟
اگر راهکارتون استفاده از websocket هست، کمی درست گفتین اما وبسوکت علاوهبر چالشهایی که داره، در حقیقت یک کانکشن دوطرفه باز میکنه که به کلاینت و سرور اجازه میده هردو اطلاعات مورد نظرشون رو ارسال کنن.
یک بار دیگه برگردیم از اول، وقتی به رکوئستهای توییتر نگاه کنین، آیا کانکشن وبسوکت میبینین؟ خیر، ارتباط وبسوکت وجود نداره، پس چطور ممکنه؟
راهحل در چنین مواری استفاده از SSE هستش. در واقع Server-Sent Events برای شما یک کانکشن realtime یک طرفه از سرور به کلاینت ایجاد میکنه که روی HTTP هستش، این کانکشن overhead کمتری داره و به هر مدت زمانیکه سرور مشخص میکنه باز میمونه و اطلاعات رو به کلاینت میفرسته.
ویژگیها:
۱. سادگی پیادهسازی
۲. مرورگرها از این ارتباط پشتیبانی میکنن
۳. اتصال مجدد خودکار در صورت قطع شدن کانکشن
۴. کاهش overhead و استفاده از یک کانکشن
#tip
یا چطور میشه خیلی سبک و بدون رکوئستهای متعدد برای کاربر نوتیفیکیشن ارسال کرد؟
اگر راهکارتون استفاده از websocket هست، کمی درست گفتین اما وبسوکت علاوهبر چالشهایی که داره، در حقیقت یک کانکشن دوطرفه باز میکنه که به کلاینت و سرور اجازه میده هردو اطلاعات مورد نظرشون رو ارسال کنن.
یک بار دیگه برگردیم از اول، وقتی به رکوئستهای توییتر نگاه کنین، آیا کانکشن وبسوکت میبینین؟ خیر، ارتباط وبسوکت وجود نداره، پس چطور ممکنه؟
راهحل در چنین مواری استفاده از SSE هستش. در واقع Server-Sent Events برای شما یک کانکشن realtime یک طرفه از سرور به کلاینت ایجاد میکنه که روی HTTP هستش، این کانکشن overhead کمتری داره و به هر مدت زمانیکه سرور مشخص میکنه باز میمونه و اطلاعات رو به کلاینت میفرسته.
ویژگیها:
۱. سادگی پیادهسازی
۲. مرورگرها از این ارتباط پشتیبانی میکنن
۳. اتصال مجدد خودکار در صورت قطع شدن کانکشن
۴. کاهش overhead و استفاده از یک کانکشن
#tip
نمونه کد اجرای یک کانکشن SSE در گولنگ:
#tip
#golang
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
#docker
#elk
GitHub
GitHub - deviantony/docker-elk: The Elastic stack (ELK) powered by Docker and Compose.
The Elastic stack (ELK) powered by Docker and Compose. - deviantony/docker-elk
👍1
این مقاله دید جالبی در رابطه با دیپلوی کردن سرویسهای داکری مطرح میکنه و دوباره موضوع مهم تگ زدن رو برامون یادآوری میکنه تا راحتتر بتونیم رولبک و از مشکلات احتمالی جلوگیری کنیم
#blog
#blog
Smartinary LLC
Why you should use immutable Docker tags
Many companies use tags such as for images of their Docker-based services. Those tags are usually automatically updated to point at the most recently built…
👏2👍1
#blog
شما با postgresql میتونید لاگ تغییرات جدولها رو داشته باشید و به صورت خودکار تمام تغییرات رو لاگ کنید. البته برای سیستمهای زیر بار یا اینترپرایز پیشنهاد نمیشه و راهحلهای بهتری هست اما این مقاله رو به این خاطر بخونید که بیشتر با postgresql و قابلیتهاش آشنا بشید.
https://www.cybertec-postgresql.com/en/tracking-changes-in-postgresql/
شما با postgresql میتونید لاگ تغییرات جدولها رو داشته باشید و به صورت خودکار تمام تغییرات رو لاگ کنید. البته برای سیستمهای زیر بار یا اینترپرایز پیشنهاد نمیشه و راهحلهای بهتری هست اما این مقاله رو به این خاطر بخونید که بیشتر با postgresql و قابلیتهاش آشنا بشید.
https://www.cybertec-postgresql.com/en/tracking-changes-in-postgresql/
CYBERTEC PostgreSQL | Services & Support
Tracking changes in PostgreSQL
UPDATED 2023 - How to track changes made to tables in PostgreSQL - instructions how to use a generic changelog trigger for tracking changes.
⚡2
#blog
#tip
نحوه نوشتن کدها در گولنگ یا همان code style guide یکی از بحثهای مهم هستش که گاها بهش کم توجه میشه.
اینکه شما باید متغیرها رو در نزدیک جایی که مورد استفاده قرار میگیرن، تعریف کنید یا شروع کردن لاگ یا پرینت با حروف بزرگ یک bad practice محسوب میشه.
این مقاله لیست کل قانونهایی که خود گوگل برای بهتر و خواناتر نوشتن گولنگ منتشر کرده و خوندنش خالی از لطف نیست.
https://google.github.io/styleguide/go/best-practices
#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
#tip
این مقاله از techblog تیندر در مورد نحوه طراحی APIهای خودشون صحبت میکنه و سناریوهایی رو میگه که هممون تجربه کردیم. مثلا همیشه میدونیم واکشی اطلاعات با متد GET انجام میشه اما در برخی اوقات نیاز داریم از متد POST استفاده کنیم. اگه وقت کردین بخونیدش نکات ریز جالبی داره و خالی از لطف نیست.
https://medium.com/tinder/tinder-api-style-guide-part-1-081804a7ef40
Medium
Tinder API Style Guide — Part 1
Authored by: Nishant Mittal
⚡2👏1