Skip to content

Commit

Permalink
Merge pull request #344 from alireza-fa/main
Browse files Browse the repository at this point in the history
Spelling correction in chapter3/3.7-select.md
  • Loading branch information
Ja7ad authored Feb 4, 2024
2 parents 9867ec3 + 37c501c commit b832cbd
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 17 deletions.
20 changes: 9 additions & 11 deletions content/chapter 3/3.7-select.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ $ go run main.go
From goOne goroutine
```

در کد فوق ما ۲ تا کانال تعریف کردیم و کانال ها را به توابع goOne و goTwo پاس دادیم سپس داخل تابع به هرکدام از کانال مقداری ارسال شد. حالا در ادامه بدنه main یک select قرار دادیم که هر یک از case ها منتظر دریافت اطلاعات از کانال مشخص شده براش است.

پس از اینکه یکی یا هر دو از کانال داده را آماده کردند بصورت تصادفی یکی از case ها انتخاب می شود تا عملیات را تکمیل کند.

که در خروجی مقداری که از ch1 آماده را نمایش می دهد. اما اگر بخواهیم خروجی هر دو کانال را ببینیم می توانیم از حلقه استفاده کنیم. به مثال زیر توجه کنید :
در کد فوق ما ۲ تا کانال تعریف کردیم و کانال ها را به توابع goOne و goTwo پاس دادیم سپس داخل تابع به هرکدام از کانال مقداری ارسال شد. حالا در ادامه بدنه main یک select قرار دادیم که هر یک از case ها منتظر دریافت اطلاعات از کانال مشخص شده‌اش است.

بلافاصله پس از‌اینکه یکی از کانال ها آماده ارسال داده شود، کیس آن اجرا می شود. اگر هر دوی کانال ها همزمان آماده ارسال داده شوند، به‌صورت تصادفی یکی از case ها انتخاب می شود تا عملیات را تکمیل کند.

که در خروجی مقداری که از ch1 آمده را نمایش می دهد. اما اگر بخواهیم خروجی هر دو کانال را ببینیم می توانیم از حلقه استفاده کنیم. به مثال زیر توجه کنید :

```go
package main
Expand Down Expand Up @@ -126,12 +124,12 @@ $ go run main.go
fatal error: all goroutines are asleep - deadlock!
```

اتفاقی که در کد فوق رخ داد ما یک کانال ایجاد کردیم و سپس داخل select یک case قرار دادیم که منتظر دریافت داده از کانال می باشد. اما چون هیچ داده به کانال ارسال نمی شود برنامه بطور کلی در همان تیکه از کد بلاک می شود و در نهایت شما با خطای داخل خروجی مواجه خواهید شد.
اتفاقی که در کد فوق رخ داد ما یک کانال ایجاد کردیم و سپس داخل select یک case قرار دادیم که منتظر دریافت داده از کانال می باشد. اما چون هیچ داده‌ای به کانال ارسال نمی شود برنامه بطور کلی در همان تیکه از کد بلاک می شود و در نهایت شما با این خطا مواجه خواهید شد.


## 3.7.1 نحوه کنترل عملیات های کانال با select

در بالا در خصوص select توضیح دادیم که چه کاربردی هایی دارد اما بزارید توضیحات را تکمیل کنیم. وقتی شما قصد دارید از گوروتین و کانال استفاده کنید در اینجا select نقش خیلی پررنگی در کنترل عملیات کانال ها دارد. اینجاست که بحث همزمانی در زبان گو خیلی زیبا می شود. select می تواند بطور همزمان داده را از کانال دریافت کند و برای اجرا سایر عملیات آماده کند. بنابراین select همراه با کانال و گوروتین خیلی ابزار قدرتمندی برای کنترل و مدیریت همگام سازی و همزمانی می شود.
در بالا در خصوص select توضیح دادیم که چه کاربردی هایی دارد اما بذارید توضیحات را تکمیل کنیم. وقتی شما قصد دارید از گوروتین و کانال استفاده کنید در اینجا select نقش خیلی پررنگی در کنترل عملیات کانال ها دارد. اینجاست که بحث همزمانی در زبان گو خیلی زیبا می شود. select می تواند بطور همزمان داده را از کانال دریافت کند و برای اجرا سایر عملیات آماده کند. بنابراین select همراه با کانال و گوروتین خیلی ابزار قدرتمندی برای کنترل و مدیریت همگام سازی و همزمانی می باشد.

### 3.7.1.1 عملیات ارسال با select

Expand Down Expand Up @@ -245,12 +243,12 @@ $ go run main.go
Timeout
```

کد کد فوق ما در یکی از case های select تابع After را به عنوان کانال دریافت کننده قرار دادیم و سپس مقدار ۱ ثانیه به تابع After پاس دادیم و پس از ۱ ثانیه select از مسدودی خارج شد.
در کد فوق ما در یکی از case های select تابع After را به عنوان کانال دریافت کننده قرار دادیم و سپس مقدار ۱ ثانیه به تابع After پاس دادیم و پس از ۱ ثانیه select از مسدودی خارج شد.


## 3.7.4 select خالی

یک select خالی و بدون case می تواند برنامه شما بطور کلی بلاک کند و باعث بروز خطای deadlock شود. اگر select خالی داخل یک گوروتین دیگری قرار گیرد آن گوروتین بطور کلی برای همیشه بلاک خواهد شد اما اگر داخل تابع main قرار دهید باعث بروز deadlock خواهد شد.
یک select خالی و بدون case می تواند برنامه شما را به‌طور کلی بلاک کند و باعث بروز خطای deadlock شود. اگر select خالی داخل یک گوروتین دیگری قرار گیرد آن گوروتین بطور کلی برای همیشه بلاک خواهد شد اما اگر داخل تابع main قرار دهید باعث بروز deadlock خواهد شد.

```go
package main
Expand All @@ -267,7 +265,7 @@ fatal error: all goroutines are asleep - deadlock!

## 3.7.5 استفاده از select در حلقه بینهایت

ما می توانیم select را داخل یک حلقه بینهایت قرار دهیم تا برای همیشه از case ها چندتا داده را بواسطه کانال دریافت کنیم و عملیاتی را انجام دهیم یا اینکه اگر قصد داریم که از هر یک از case ها داده‌ای را دریافت کردیم حلقه را متوقف کنیم اینکار را هم بواسطه return می توانیم انجام دهیم.
ما می توانیم select را داخل یک حلقه بینهایت قرار دهیم تا برای همیشه از case ها چندتا داده را بواسطه کانال دریافت کنیم و عملیاتی را انجام دهیم. همچنین اگر قصد داریم که آنقدر کیس ها چک شوند تا یکی از کانال ها برای ارسال و یا دریافت داده آماده باشد، می توانیم از این روش استفاده کنیم و در نهایت با return کردن از حلقه بینهایت خارج شویم.

```go
package main
Expand Down Expand Up @@ -370,7 +368,7 @@ case n := <-news:

## 3.7.7 استفاده از break در select

شما می توانید break داخل هر یک از case های select استفاده کنید.
شما می توانید break را داخل هر یک از case های select استفاده کنید.

```go
import "fmt"
Expand Down
12 changes: 6 additions & 6 deletions content/chapter 3/3.8-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ weight: 5008

پکیج [context](https://pkg.go.dev/context) یک پکیج built-in است که یکی از پرکاربرد ترین پکیج های زبان گو می باشد. کار اصلی این پکیج فراهم کردن بستری است که بتوان به داده های مشترک دسترسی داشت و یا بتوان آنها را به اشتراک گذاشت و مدیریت کرد. حتی اگر شما نخواسته باشید سمت این پکیج بروید به مرور زمان که جلوتر می روید با این پکیج رو به رو خواهید شد و مجبور خواهید بود این پکیج را یاد بگیرید.

این پکیج چندان بزرگ نیست و شاید بتوانید توابع و مفاهیم آن را حیلی زود یاد بگیرید اما دقت کنید یک روزی این پکیج میشه تبدیل به بنیادی ترین قسمت از کدهایتان خواهد شد.
این پکیج چندان بزرگ نیست و شاید بتوانید توابع و مفاهیم آن را خیلی زود یاد بگیرید اما حتما یک روزی این پکیج تبدیل به یکی از بنیادی ترین قسمت های کدتان خواهد شد.

در این بخش از کتاب سعی خواهد شد مفاهیم context به صورت ساده و قابل درکی بیان شود.
در این بخش از کتاب سعی خواهد شد مفاهیم context به صورت ساده و قابل درک، بیان شود.

## 3.8.1 context چیست؟

در واقع context مانند یک درخت می باشد که کلی شاخه دارد و هر شاخه به شاخه های ریزتری تقسیم شده و در نهایت به برگ ها و میوه های درخت منتهی می شوند. حال شما می توانید در هر ناحیه شاخه والد را قطع کنید تا شاخه های فرزند از بین برود.
در زبان گو `context` یک اینترفیس است که یکسری متد دارد که هریک از متدها می تواند عملیاتی را انجام دهد و این امکان را فراهم می کند هر وقت یک درخواست از سمت کلاینت به سرور می آید این درخواست می تواند در لایه های مختلف منتهی شود و داخل context می تواند یکسری key/value های مهم باشد که شما بتوانید در هر لایه، به آنها دسترسی داشته باشید و همچنین در صورت لزوم می توانید سیگنال cancel بفرستید که درخواستی که تا هرجا رفته است کنسل شود.

در ادامه با یک طرح یم مثال ساده به درک بهتر این موضوع کمک می کنیم :
در ادامه با طرح یک مثال ساده به درک بهتر این موضوع کمک می کنیم :

{{<img url="#" image="../../assets/img/content/chapter3/context/3.jpg" alt="context diagram">}}

فرض کنید یک سرور http راه اندازی کردید (در فصل ۵ آشنا خواهید شد) که یکسری آدرس API دارد که کلاینت می تواند با استفاده از این آدرس ها با سرور شما ارتباط برقرار کند و عملیات مشخصی را انجام دهد. حال وقتی کلاینت درخواست می دهد. درخواست تا زمانیکه کامل شود و خروجی به کاربر نمایش داده شود می توانید این درخواست را بواسطه context در لایه های مختلف پروژه خود منتهی کنید و یکسری عملیات یا اطلاعات را در هر لایه از context بگیرید. اگر به دیاگرام فوق نگاه کنید اگر کلاینت درخواستش را لغو کند و درخواست کاربر به واسط context تا لایه Manager رفته باشد می تواند این درخواست در همان لایه متوقف شود و عملیات تکمیل نشود.
فرض کنید یک سرور http راه اندازی کردید (در فصل ۵ آشنا خواهید شد) که یکسری آدرس API دارد که کلاینت می تواند با استفاده از این آدرس ها با سرور شما ارتباط برقرار کند و عملیات مشخصی را انجام دهد. حال وقتی کلاینت درخواست می دهد. درخواست تا زمانیکه کامل شود و خروجی به کاربر نمایش داده شود می توانید این درخواست را بواسطه context در لایه های مختلف پروژه خود منتهی کنید و یکسری عملیات یا اطلاعات را در هر لایه از context بگیرید. اگر به دیاگرام فوق نگاه کنید اگر کلاینت درخواستش را لغو کند و درخواست کاربر به واسط context تا لایه Manager رفته باشد می تواند این درخواست در همان لایه متوقف شود و عملیات تکمیل نشود.

{{< hint info >}}
برای درک بهتر مثال فوق بهتره فایل صوتی زیر را گوش دهید تا بهتر بتوانید درک کنید :
Expand Down Expand Up @@ -76,7 +76,7 @@ type Context interface {

#### context.Background() :

داخل پکیج context ما یک تابع داریم به نام Background یک اولین context خام و والد را میسازد و به شما یک اینترفیس از نوع Context می دهد.
داخل پکیج context ما یک تابع داریم به نام Background که اولین context خام و والد را میسازد و به شما یک اینترفیس از نوع Context می دهد.

1. این context ایجاد شده هیچ مقداری داخلش ندارد.
2. هیچ وقت نمی تواند کنسل شود.
Expand Down Expand Up @@ -225,7 +225,7 @@ Go

## 3.8.5 تابع context.WithCancel

زمانیکه شما با استفاده از تابع WithCancel یک context فرزند ایجاد می کنید ۲ تا خروجی به شما می دهد اولی context و دومی تابع cancel می باشد. که شما می توانید تابع cancel را برای لغو درخواستی که از سمت کلاینت یا لایه های بالاتر اومده را انجام دهید.
زمانیکه شما با استفاده از تابع WithCancel یک context فرزند ایجاد می کنید ۲ تا خروجی به شما می دهد اولی context و دومی تابع cancel می باشد. که شما می توانید تابع cancel را برای لغو درخواستی که از سمت کلاینت یا لایه های بالاتر اومده را انجام دهید.

```go
type CancelFunc func()
Expand Down

0 comments on commit b832cbd

Please sign in to comment.