Syntax | سینتکس – Telegram
Gracefully shutdown

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

مدیریت سیگنال‌ها

- سیگنال‌ها: سیستم‌عامل‌ها سیگنال‌هایی مثل SIGTERM یا SIGINT را برای اطلاع‌رسانی به برنامه‌ها ارسال می‌کنند که باید خاموش شوند.
لیستی از سیگنال های LINUX. هر سیگنال معنی خاص خودش رو داره. SIGTERM به معنی سیگنالی هستش که برای Process termination ارسال شده است.
https://faculty.cs.niu.edu/~hutchins/csci480/signals.htm

- واکنش به سیگنال‌ها: برنامه باید این سیگنال‌ها را مدیریت کرده و فرآیند خاموشی را آغاز کند.

پردازش درخواست‌های جاری

- تکمیل درخواست‌ها: برنامه باید مطمئن شود که تمامی درخواست‌های در حال پردازش به اتمام می‌رسند و پاسخ‌ها به‌طور کامل ارسال می‌شوند.
- پذیرش درخواست جدید: ممکن است لازم باشد که پذیرش درخواست‌های جدید متوقف شود تا منابع آزاد شوند.

مدیریت منابع

- بستن اتصالات: همه‌ی اتصالات باز به پایگاه‌های داده و سوکت‌ها باید به‌صورت ایمن بسته شوند.
- آزادسازی حافظه: برنامه باید تمام حافظه‌های تخصیص داده‌شده را آزاد کند تا از نشت حافظه جلوگیری شود.

ذخیره‌سازی وضعیت

- ذخیره‌سازی وضعیت برنامه: در برنامه‌های حالت‌گرا، وضعیت فعلی باید ذخیره شود تا در راه‌اندازی مجدد قابل بازیابی باشد.
- ثبت لاگ‌ها: ثبت وقایع و لاگ‌های مهم برای عیب‌یابی ضروری است.

هماهنگی با سرویس‌های دیگر

- اطلاع‌رسانی به سرویس‌های وابسته: اگر برنامه با سرویس‌های دیگر تعامل دارد، باید به آن‌ها اطلاع دهد که در حال خاموش شدن است تا آن‌ها بتوانند اقدامات لازم را انجام دهند.

پیاده‌سازی در زبان‌های مختلف
- جاوا: استفاده از Shutdown Hook برای اجرای کد لازم در زمان خاموشی.
- پایتون: استفاده از کتابخانه signal برای مدیریت سیگنال‌ها و اجرای فرآیندهای نهایی.
- Node.js: مدیریت خاموشی با استفاده از رویدادهای process مانند SIGINT.

#gracefully_shutdown

@Syntax_fa
👍51🔥1
مراحل دپلوی:

مرحله اول
1. نوشتن کد ها
2. ران کردن تست با استرس
موفقیت آمیز:
- به جدم کسی نیست در حدم
ناموفق:
- من چقدر برنامه نویس بدبختی هستم 😔

مرحله دوم
1. تصحیح کد ها
2. ران کردن تست با استرس فراوان
موفقیت:
- خدایا شکرت
ناموفق:
خشم فروان

مرحله سوم
1. تصحیح دوباره کد ها
2. ران کردن تست
3. تستا چه موفق بود چه ناموفق دپلوی کن بره

#fun

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣20👍7😁3
یبار برا همیشه Cron expressions رو یاد بگیر

برای زمان‌بندی خودکار دستورات یا اسکریپت‌ها استفاده می‌شود. این ابزار در سیستم‌عامل‌های یونیکس و لینوکس رایج است و در ابزارهایی مثل Jenkins، Kubernetes و غیره هم کاربرد دارد. Cron expressions از پنج یا شش فیلد تشکیل شده‌اند که هر کدام بیانگر یک واحد زمانی است:

* * * * * [دستور]
| | | | |
| | | | +--- روزهای هفته (۰-۷) (۰ و ۷ برای یکشنبه)
| | | +----- ماه (۱-۱۲)
| | +------- روز ماه (۱-۳۱)
| +--------- ساعت (۰-۲۳)
+----------- دقیقه (۰-۵۹)


مثال‌ها

1. اجرای دستور هر دقیقه:

 
   * * * * *
  

2. اجرای دستور هر روز در ساعت ۳:۳۰ صبح:

 
   30 3 * * *
  

3. اجرای دستور هر یکشنبه ساعت ۵ عصر:

 
   0 17 * * 0
  

4. اجرای دستور در روز اول هر ماه ساعت ۱۲ ظهر:

 
   0 12 1 * *
  

5. اجرای دستور هر ۵ دقیقه:

 
   */5 * * * *
  

6. اجرای دستور هر دو ساعت:

 
   0 */2 * * *
  

علائم خاص

- **ستاره (*)**: همه مقادیر ممکن را شامل می‌شود

خط فاصله (-)-): برای تعیین بازه از-تا استفاده می‌شود. مثلاً 1-5

کاما (,),): برای تعیین مقادیر مختلف در یک فیلد استفاده می‌شود. مثلاً 1,3,5 یعنی روز ۱، ۳ و ۵

اسلش (/)/): برای تعیین گام‌های تکرار استفاده می‌شود. مثلاً */15 در فیلد دقیقه یعنی هر ۱۵ دقیقه.

مثال پیچیده‌تر

اجرای یک دستور در ساعت ۱:۱۵ بعد از ظهر هر دوشنبه و چهارشنبه:

15 13 * * 1,3

همچنین اکثر scheduler ها از cron expressions پشتیبانی میکنن. پس یبار یاد بگیر همه جا استفاده کن🍸

#cron_expression

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13💋4🔥2👌1
یه رابطه عاطفی خوب از نگاه یه برنامه نویس😒:

1. ریسپانس تایم پایین:
هر بار که پیامی به پارتنرت می‌فرستی، باید تو چند ثانیه پاسخ بده. اصلا یدونه تایم اوت یه دقیقه بذار اگه بعد یه دقیقه پاسخی دریافت نکردی کلا راه ارتباطی بلاک شه!

2. دیباگ کردن مشکلات:
هر وقت مشکلی پیش میاد، به جای نادیده گرفتن، باید بشینیم دیباگ کنیمش و ببینیم مشکل کجاست تا فیکسش کنیم. اگه مشکلاتو نادیده بگیریم بعدا ممکنه کل سیستمو نابود کنه

3. ورژن کنترل:
هر تصمیم مهمی باید توی یک سیستم ورژن کنترل ثبت بشه. اینطوری می‌تونیم به راحتی برگردیم و تغییرات رو بررسی کنیم.

4. فایروال:
برای جلوگیری ورود بیگانه، یه فایروال قوی باید داشته باشیم که هر آدم بی‌مورد رو بلاک کنه.

5. آپ‌تایم رابطه:
سرور رابطه باید همیشه آپ‌تایم باشه. اگر داون‌تایم زیادی داشته باشه، ممکنه کاربران (هر دو نفر) نارضایتی پیدا کنن.

6. پچ‌های امنیتی:
هر چند وقت یک‌بار باید پچ‌های امنیتی برای رفع باگ‌های قدیمی اعمال بشه تا هیچ‌وقت به مشکل نخوریم.

7. پشتیبان‌گیری منظم:
از خاطرات خوب باید به‌صورت منظم بک‌آپ گرفته بشه تا در مواقع سخت بتونیم بهشون رجوع کنیم.

8. UI/UX دلپذیر:
هیچوقت فقط بخاطر ui جذاب یکیو انتخاب نکن. خیلی مهمه در کنار ui حتما ux خوبیم داشته باشه.
شدنیه فقط بخاطر ux بشه کنار اومد ولی فقط ui شدنی نیست.

#fun

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18😁5👍4💋4👎3🤣3🥰2
الگوی Retry (Retry Pattern)

الگوی Retry به برنامه‌نویسان کمک می‌کند تا در مواجهه با خطاهای موقتی، به‌طور خودکار تلاش مجدد کنند. این الگو به ویژه در تعاملات شبکه‌ای، مانند درخواست‌های HTTP یا دسترسی به پایگاه داده، مفید است. هدف این است که اگر یک عملیات ناموفق بود، به‌جای شکست فوری، چند بار دیگر نیز امتحان شود.

مزایای الگوی Retry


- افزایش قابلیت اطمینان: کاهش احتمال شکست به دلیل مشکلات موقتی.
- بهبود تجربه کاربری: کاربران با خطاهای موقتی مواجه نمی‌شوند.
- مدیریت بهینه منابع: می‌توان به جای تلاش‌های بی‌پایان، تعداد تلاش‌ها را محدود کرد.

نحوه استفاده در پایتون


در پایتون، می‌توان از یک حلقه و استثناها برای پیاده‌سازی این الگو استفاده کرد. در زیر یک مثال ساده از نحوه استفاده از الگوی Retry آورده شده است.

مثال:


import time
import random

def unreliable_function():
if random.random() < 0.7:
raise Exception("an error occurred")
return "OK"

def retry(func, retries=3, delay=2):
for attempt in range(retries):
try:
result = func()
return result
except Exception as e:
print(f"try again. retry time: %d" % retries)
time.sleep(delay)
raise Exception("unexpected error")

# Retry Pattern
result = retry(unreliable_function)
print(result)


### توضیحات کد:

- unreliable_function: تابعی که 70% احتمال خطا دارد.
- retry: تابعی که عملیات را دوباره امتحان می‌کند. تعداد تلاش‌ها و تأخیر بین آن‌ها را می‌توان تعیین کرد.
- حلقه: در صورتی که عملیات ناموفق باشد، یک پیام خطا چاپ می‌شود و برنامه به مدت مشخصی منتظر می‌ماند و دوباره تلاش می‌کند.
- نتیجه: در نهایت، یا نتیجه موفقیت‌آمیز تابع اصلی برمی‌گردد یا پیامی مبنی بر ناموفق بودن همه تلاش‌ها.

با استفاده از این الگو، می‌توانید به راحتی عملیات خود را در مواجهه با خطاهای موقتی بهبود بخشید.
💋5👍4🔥31🥰1
یچی جالب که تو نسخه 12 پستگرس اضافه کرده بودن قابلیت rest api بودش
مثلا میتونستید با استفاده از rest api ها بیاید عملیات crud رو انجام بدید قابلیت authorization با jwt توکن هم داره

https://docs.postgrest.org/en/v12/tutorials/tut0.html

#fun

@Syntax_fa
👍10💋6👀42👎1
Context awareness

در بک‌اند، مفهوم context awareness به توانایی یک سیستم برای درک و پاسخ به شرایط و اطلاعات موجود در یک درخواست اشاره دارد. این ویژگی به توسعه‌دهندگان کمک می‌کند تا اپلیکیشن‌هایی بسازند که به صورت پویا و کارآمد با درخواست‌های مختلف تعامل داشته باشند. چند جنبه مهم از context awareness:

دسترسی به مقادیر درخواست

در یک اپلیکیشن بک‌اند، دسترسی به مقادیر مختلف در یک درخواست (مثل هدرها، پارامترهای کوئری، و بدنه درخواست) بسیار مهم است. این مقادیر می‌توانند برای احراز هویت، و پردازش داده‌ها و ... استفاده شوند.

مدیریت لغو درخواست

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

برای مثال:
- پایان دادن به کوئری‌های دیتابیس: وقتی درخواست لغو می‌شود، بهتر است کوئری‌های در حال اجرا در دیتابیس را متوقف کنید تا منابع سیستم آزاد شوند.
- لغو پردازش‌های سنگین: اگر پردازشی طولانی در حال انجام است، لغو آن می‌تواند به بهبود کارایی سیستم کمک کند.

پیاده‌سازی در گولنگ:

در زبان‌ Go، از context.Context استفاده می‌شود که به شما اجازه می‌دهد درخواست‌ها را ردیابی کرده و در صورت لغو، عملیات مرتبط را متوقف کنید.
در Go، استفاده از context.Context به صورت زیر است:

func HandleRequest(ctx context.Context, db *sql.DB) {
    query := "SELECT * FROM users"
    rows, err := db.QueryContext(ctx, query)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        // پردازش داده‌ها
    }
}

در این مثال، اگر ctx کنسل شود، کوئری دیتابیس هم متوقف خواهد شد.

#contex_awareness

@Syntax_fa
👍13💋11🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
بچم از طریق اینستا با یه استاد برنامه نویسی آشنا شده داره برنامه نویسی یاد می گیره😍😍

محتوای آموزشی استاد اینستاییش:

#fun

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
💋27🤣16🥰1
از پایتون 3.13 چخبر؟ 🍸

1. یک مفسر تعاملی (Interactive Interpreter) بهتر

پایتون 3.13 بهبودهای قابل توجهی در مفسر تعاملی به همراه پیام‌های خطای پیشرفته معرفی می‌کند. مفسر تعاملی جدید اکنون از رنگ‌بندی پشتیبانی می‌کند و تجربه‌ای بصری‌تر ارائه می‌دهد. این پشتیبانی از رنگ به tracebacks و خروجی doctest نیز گسترش می‌یابد. کاربران می‌توانند رنگ‌بندی را از طریق متغیرهای محیطی PYTHON_COLORS و NO_COLOR غیرفعال کنند.

علاوه بر این، پایتون 3.12 شامل یک کامپایلر JIT (Just-In-Time) اولیه بر اساس PEP 744 است. اگرچه در حال حاضر به‌طور پیش‌فرض غیرفعال است، این کامپایلر نشان‌دهنده بهبودهای عملکردی امیدوارکننده‌ای است و برنامه‌هایی برای بهبودهای بیشتر در نسخه‌های بعدی وجود دارد.

2. کامپایل آزمایشی Just-in-Time (JIT)


پایتون یک کامپایلر آزمایشی just-in-time (JIT) معرفی می‌کند که در صورت فعال‌سازی، می‌تواند برخی برنامه‌های پایتون را سریع‌تر کند. کامپایلر JIT با ترجمه bytecode تخصصی Tier 1 به یک نمایش میانی داخلی Tier 2 جدید کار می‌کند که برای ترجمه به کد ماشین بهینه شده است. چندین مرحله بهینه‌سازی به Tier 2 IR اعمال می‌شود قبل از اینکه تفسیر یا به کد ماشین ترجمه شود. گزینه‌های پیکربندی (–enable-experimental-jit) به کاربران اجازه می‌دهد تا رفتار JIT را در زمان ساخت و اجرا کنترل کنند، از جمله فعال یا غیرفعال کردن JIT و مفسر Tier

مزایای بالقوه کامپایلر JIT:
بهبود عملکرد قابل توجه برای بخش‌های خاصی از کد که از اجرای کد ماشین سود می‌برند.
امکان بهینه‌سازی‌های آینده که قبلاً با تفسیر bytecode ممکن نبودند.

3. سی پایتون (CPython) آزمایشی بدون GIL

سی پایتون اکنون از اجرای بدون Global Interpreter Lock (GIL) پشتیبانی می‌کند، که امکان اجرای multithreadding آزاد را با پیکربندی –disable-gil فراهم می‌سازد. اجرای چندریسمانی آزاد به بهره‌برداری بهتر از هسته‌های CPU موجود از طریق اجرای موازی ریسمان‌ها کمک می‌کند و به برنامه‌هایی که برای threading طراحی شده‌اند، سود می‌رساند.
ماژول‌های توسعه C-API باید به‌طور خاص برای ساختار چندریسمانی آزاد ساخته شوند و باید با استفاده از مکانیزم‌های مناسب، پشتیبانی از اجرای بدون GIL را نشان دهند.

4. گزارش‌دهی و راهنمایی خطای بهبود یافته

ردیابی خطا در پایتون در نسخه جدید بهبود یافته است. مفسر اکنون پیام‌های خطا را به‌طور پیش‌فرض هنگام نمایش tracebacks رنگی می‌کند. در ویژگی دیگر، پیام خطا در صورت ارسال یک کلیدواژه اشتباه به یک تابع، کلیدواژه صحیح را پیشنهاد می‌دهد.

گاهی اوقات که یک اسکریپت همنام یک ماژول کتابخانه استاندارد است، پایتون اکنون پیام خطای دقیقی ارائه می‌دهد و پیشنهاد می‌کند برای درک بهتر، نام ماژول تغییر کند.
>>> sys.version_info
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined. Did you forget to import 'sys'!

5. جمع‌آوری زباله افزایشی

پایتون 3.12 جمع‌آوری زباله افزایشی را معرفی می‌کند که زمان توقف حداکثر را برای هیپ‌های بزرگتر به طور قابل توجهی کاهش می‌دهد. این بهبود به‌ویژه برای برنامه‌هایی با تخصیص و آزادسازی حافظه زیاد مفید است.
# Python 3.12
import gc
gc.isincremental()  # Returns True

این ویژگی به برنامه‌های پایتون اجازه می‌دهد تا روان‌تر اجرا شوند و تأثیر توقف‌های جمع‌آوری زباله کاهش یابد، که به بهبود عملکرد کلی و واکنش‌پذیری منجر می‌شود.

6. بهینه‌سازی حافظه برای Docstrings


پایتون 3.13 تغییری ظریف اما مؤثر برای بهبود کارایی حافظه معرفی می‌کند: بهینه‌سازی حافظه برای Docstrings. این ویژگی منبع پنهانی از استفاده حافظه و اندازه فایل مرتبط با docstrings در کد پایتون را هدف قرار می‌دهد.

محدودیت‌های Docstrings سنتی در پایتون به شرح زیر است:
به‌طور سنتی، docstrings در پایتون شامل هر گونه فاصله تورفتگی ابتدایی بودند. در حالی که این فضاهای اضافی به نظر بی‌ضرر می‌آیند، به اندازه کلی فایل‌های bytecode کامپایل‌شده (.pyc) افزوده و احتمالاً استفاده از حافظه را هنگام اجرای کد افزایش می‌دادند.

مزایای بهینه‌سازی حافظه برای Docstrings:
بهینه‌سازی حافظه برای Docstrings این ناکارآمدی را برطرف می‌کند. به‌طور خودکار هر گونه تورفتگی ابتدایی را از docstrings قبل از فرآیند کامپایل حذف می‌کند.
این اطمینان می‌دهد که تنها محتوای واقعی docstring ذخیره می‌شود، که منجر به:
کاهش استفاده از حافظه برای فایل‌های bytecode کامپایل‌شده.
احتمالاً کاهش استفاده از حافظه در هنگام اجرای برنامه، به‌ویژه برای پروژه‌هایی با docstring گسترده.

Source

#python

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13💋3👍21🥰1
اولین نسخه از زبون GoSharp منتشر شد 👍

زبان GoSharp یک فورک از Golang هستش

تبریک به سی هشتگ ها که یک رقیب جدید پیدا کردن و گو هشتگ هم اضافه شد.

با اولین فیچری که اضافه شد، شما می‌تونید فقط با نوشتن یک '?' ، خطا رو بدون نوشتن if err != nil برگردونید.

مخزن گیت‌هاب
https://github.com/0x9n0p/gosharp

source

#news

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
💋8😁3🔥2🤣2👍1
بنظر دو ماه پیش سینتکس یساله شده بود تازه متوجه شدم.

سعی کردم به این شکل پیش بریم که محتوای کانال نه خیلی جدی باشه نه خیلی اینستایی
جمعی دوستانه که در کنار هم یاد بگیریم و بخندیم

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

و جمع دیگری از اساتید که اسمشونو نبردم.
🤣194💋4👀3🎉2👍1🔥1🤨1
پروتکل بافر (Protocol Buffers)

پروتکل بافر یک روش سریالیزیشن داده‌ها است که به شما اجازه می‌دهد داده‌ها را به صورت ساختاریافته و بهینه ذخیره و منتقل کنید. این روش به‌ویژه در سیستم‌های توزیع‌شده و میکروسرویس‌ها کاربرد فراوانی دارد.

مزایای پروتکل بافر:

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

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

مثال: استفاده از پروتکل بافر در یک سیستم Message Driven

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

۱. تعریف پیام‌ها

ابتدا ساختار پیام‌ها را در یک فایل .proto تعریف می‌کنیم:

syntax = "proto3";

package user;

message User {
    string name = 1;
    int32 age = 2;
}


۲. تولید کد گولنگ

برای تولید کد گولنگ، ابتدا باید ابزار protoc و پلاگین Go را نصب کنید:

go get google.golang.org/protobuf/cmd/protoc-gen-go


سپس، کد گولنگ را با دستور زیر تولید کنید:

protoc --go_out=. user.proto


۳. ارسال پیام به سیستم Message Driven


حالا بیایید یک تولیدکننده پیام ایجاد کنیم که یک کاربر را سریالیزه کرده و به یک صف پیام (مثل Kafka) ارسال کند.

package main

import (
    "log"
    "github.com/confluentinc/confluent-kafka-go/kafka"
    "google.golang.org/protobuf/proto"
    "your_project/user"
)

func main() {
    producer, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": "localhost:9092"})
    if err != nil {
        log.Fatal(err)
    }
    defer producer.Close()

    // create user
    user := &user.User{
        Name: "Alice",
        Age:  30,
    }

    // serialize data
    data, err := proto.Marshal(user)
    if err != nil {
        log.Fatal("Failed to serialize user:", err)
    }

    // publish a message
    topic := "users"
    err = producer.Produce(&kafka.Message{
        TopicPartition: kafka.TopicPartition{Topic: &topic, Partition: kafka.PartitionAny},
        Value:          data,
    }, nil)

    if err != nil {
        log.Fatal("Failed to send message:", err)
    }

    producer.Flush(15 * 1000)
    log.Println("User sent to Kafka:", user.Name)
}


۴. کانسیوم پیام از سیستم Message Driven


حالا بیایید یک consumer پیام بسازیم که پیام‌های دریافتی را دی‌سریالیزه کند:

package main

import (
    "log"
    "github.com/confluentinc/confluent-kafka-go/kafka"
    "google.golang.org/protobuf/proto"
    "your_project/user"
)

func main() {
    consumer, err := kafka.NewConsumer(&kafka.ConfigMap{
        "bootstrap.servers": "localhost:9092",
        "group.id":          "user_group",
        "auto.offset.reset": "earliest",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer consumer.Close()

    consumer.SubscribeTopics([]string{"users"}, nil)

    for {
        msg, err := consumer.ReadMessage(-1)
        if err != nil {
            log.Println("Error reading message:", err)
            continue
        }

        // deserialization
        receivedUser := &user.User{}
        if err := proto.Unmarshal(msg.Value, receivedUser); err != nil {
            log.Println("Failed to unmarshal user:", err)
            continue
        }

        // use info
        log.Printf("Received User: Name: %s, Age: %d\n", receivedUser.Name, receivedUser.Age)
    }
}


#protocol_buffer

@Syntax_fa
💋8👍5❤‍🔥3😁1
تو چند دقیقه نحوه کار با Redis Pub/Sub رو تو پایتون یاد بگیر

Pub/Sub
(انتشار/اشتراک) یک الگوی معماری است که به برنامه‌ها اجازه می‌دهد تا به صورت غیرمستقیم با یکدیگر ارتباط برقرار کنند. در این الگو، تولیدکنندگان اطلاعات (Publisher) پیام‌ها را منتشر می‌کنند و مصرف‌کنندگان (Subscriber) به موضوعات (Topics) خاصی که به آن‌ها علاقه‌مند هستند، اشتراک می‌گذارند. این سیستم اجازه می‌دهد تا بدون نیاز به وابستگی مستقیم با یکدیگر، اطلاعات را تبادل کنند.

مزایای Pub/Sub
- کاهش وابستگی‌ها: تولیدکنندگان و مصرف‌کنندگان نیازی به شناخت یکدیگر ندارند.
- مقیاس‌پذیری: می‌توان به سادگی مصرف‌کنندگان و تولیدکنندگان جدیدی اضافه کرد.
- توزیع‌پذیری: می‌توان سیستم‌ها را به صورت توزیع‌شده پیاده‌سازی کرد.

مثال ساده با Redis Pub/Sub


در این مثال، از Redis به عنوان سیستم Pub/Sub استفاده خواهیم کرد. ابتدا باید Redis را نصب و راه‌اندازی کنید.

نصب Redis

تو ریپازیتوری ای که لینکشو آخر پست میذارم، سرویس ردیس رو توی docker-compose.yml مشخص کردم و روی داکر اجراش میکنیم.
همچنین داخل فایل .env تنظیمات ردیس رو میتونید مشخص کنید.

docker-compose up -d


پیاده‌سازی در پایتون

برای این کار به کتابخانه redis نیاز داریم. می‌توانید آن را با pip نصب کنید:

pip install redis



در این مثال، یک Publisher و یک Subscriber خواهیم داشت.

Publisher (server.py):

import json

from redis import StrictRedis


server = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)

# redis ping
print(server.ping())

topic = "example_topic"

data = {
"name": "alireza",
"age": 22,
}

server.publish(channel=topic, message=json.dumps(data))


در قدم اول کانکشن با ردیس رو می سازیم.
با متد ping میتونیم چک کنیم وضعیت کانگشنمون اوکی هست یا نه(جنبه آموزشی نوشتمش)
بعد مشخص کردیم که topic ما اسمش چیه.
دیتایی که قراره داخل payload مسیج قرار بدیم رو مشخص کردیم که بصورت دیکشنری هستش و بعدش اومدیم به json تبدیلش کردیم و مسیح رو پابلیش کردیم.

Subscriber (client.py):

import json

from redis import StrictRedis


client = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)

topic = "example_topic"

pubsub = client.pubsub()

pubsub.subscribe(topic)

print("waiting for message...")

while True:
for message in pubsub.listen():
if message["data"] == 1:
continue
match message["type"]:
case topic:
# TODO - change serialization. json is not good
data = json.loads(message["data"])
print("received message", data["name"], data["age"])

در قدم اول یک کانکشن ردیس گرفتیم. بعد تاپیکی که subscribe میکنیمش رو مشخص کردیم(میتونیم چندین تا تاپیک رو سابسکرایب کنیم)
در قدم بعدی داخل یک long running میایم به مسیج های جدیدی که میاد گوش میدیم و یک switch case زدیم و براساس تاپیک ها میتونیم کارهای خاص خودش رو انجام بدیم.

نحوه اجرا

1. در یک ترمینال، client.py را اجرا کنید
2. در یک ترمینال دیگه server.py رو اجرا کنید که با هربار اجرا یک مسیج رو پابلیش میکنه.

سورس کد:
https://github.com/alireza-fa/redis-pub-sub-example

#redis_pub_sub #pub_sub #event_driven #python

@Syntax_fa
🔥6💋4👍31👎1🙏1
بررسی نحوه کارکرد توکن jwt

یک توکن JWT از سه بخش تشکیل شده است:

Header:
در هدر، الگوریتم مورد استفاده برای امضا مشخص می‌شود. این می‌تواند الگوریتم‌های مختلفی باشد که در ادامه توضیح داده خواهد شد.

Payload:
در این بخش، اطلاعات مورد نیاز قرار می‌گیرد. به‌صورت پایه‌ای، user_id کاربری که توکن برای او صادر شده و فیلد exp برای تاریخ انقضای توکن (به صورت timestamp) ضروری است.

Signature:
این بخش برای صحت‌سنجی توکن استفاده می‌شود که در ادامه روش آن توضیح داده خواهد شد.

بنابراین، توکن ما سه بخش دارد. قسمت‌های header و payload به‌صورت یک آبجکت با کلید و مقدار هستند. به‌عنوان مثال، هدر به این صورت است:
{"alg": "HS256"}

و قسمت payload به این صورت:
{"user_id": 1, "exp": 111222558}


برای بازگرداندن یک رشته یکپارچه به کلاینت، این سه بخش را به روش زیر ترکیب می‌کنیم:

1. Base64Url Encoding:
قسمت‌های header و payload را به Base64Url تبدیل می‌کنیم. Base64Url رشته‌ای برمی‌گرداند که شامل کاراکترهای ASCII اصلی است.

2. ترکیب بخش‌ها:

پس از تبدیل به Base64Url، بخش‌های header و payload را با . به یکدیگر متصل می‌کنیم:

   header.payload

3. ساخت Signature:
بر اساس header.payload و با استفاده از الگوریتم مشخص‌شده و یک کلید محرمانه در سرور، امضا ساخته می‌شود. سپس امضا را با . به رشته اضافه می‌کنیم:
   header.payload.signature


استفاده از JWT:

کلاینت توکن را در هر درخواست احراز هویت ارسال می‌کند (معمولاً در هدر درخواست).
توکن با «نقطه» به سه بخش جدا می‌شود:

1. دیکود کردن Header:

هدر را از Base64Url دیکود کرده و الگوریتم آن را بررسی می‌کنیم.

2. اعتبارسنجی Signature:

با استفاده از الگوریتم و کلید سرور، signature محاسبه و با signature موجود مقایسه می‌شود. در صورت عدم تطابق، توکن نامعتبر است.

3. بررسی Payload:

پیلود را دیکود کرده و فیلد exp را با زمان فعلی مقایسه می‌کنیم. اگر زمان انقضا گذشته باشد، توکن نامعتبر است. در غیر این صورت توکن معتبر است و می‌توان از user_id برای دسترسی به اطلاعات کاربر استفاده کنیم.

تفاوت بین Access Token و Refresh Token:

هر دو ساختار مشابهی دارند. در برخی پروژه‌ها، در payload فیلدی به نام type اضافه می‌کنیم که مشخص می‌کند توکن access است یا refresh. از access token برای احراز هویت کاربر و از refresh token برای دریافت یک access token جدید استفاده می‌شود.

یکی از دلایل استفاده از دو نوع توکن که استفاده کردم:
- Access Token:

ممکن است شامل اطلاعات بیشتری مانند نقش‌ها و پروفایل کاربر باشد. اگر نقش کاربر تغییر کند (مثلاً دیگر ادمین نباشد)، می‌توان access tokens او را نامعتبر کرد و با استفاده از refresh token یک access token جدید صادر کرد که نقش ادمین ندارد.

- Refresh Token:

معمولاً فقط شامل user_id و exp است و برای امنیت بیشتر می‌توان ip_address و device_name را نیز اضافه کرد. این اطلاعات برای ایجاد یک access token جدید استفاده می‌شود.

#jwt

@Syntax_fa
👍20👌3💋3
دات نت کارها: وردپرس کارهای دنیای برنامه‌نویسی

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

ورود به دنیای دات نت

ورود به دنیای دات نت مثل ورود به یک فروشگاه بزرگ است که همه چیز در آن وجود دارد. از ابزارهای مدیریتی گرفته تا کتابخانه‌های مختلف و فریمورک‌های پیشرفته. دات نت کارها با افتخار از ابزارهای مایکروسافت استفاده می‌کنند و همیشه آماده‌اند تا با آپدیت‌های جدید ویژوال استودیو به‌روز شوند. درست مثل وردپرس کارها که همیشه منتظر آپدیت افزونه‌ها و قالب‌های جدید هستند!

سفارشی‌سازی آسان

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

جامعه‌ی خاص

جامعه‌ی دات نت کارها مثل یک کافه‌ی شلوغ است که همه در حال بحث درباره‌ی چیزهای شت هستند. دات نت کارها همیشه در حال بحث درباره‌ی جدیدترین آپدیت‌های مایکروسافت هستند، درست مثل وردپرس کارها که درباره‌ی بهترین افزونه‌های سئو صحبت می‌کنند.
(داداش آپدیت جدیدو دیدی عجب خفنه کلی فیچر اضافه کرده!)

پیمان وفاداری

دات نت کارها قسم خورده اند در هرشرایط و هرکجا حتی به شوخی نسبت به دات نت چیزی گفته شود، از دات نت دفاع کنند.
معمولا چند ساعت از روز را برای بحث و دفاع از دات نت کنار می‌گذارند.

#fun

@Syntax_fa
🤣28👍4👎3👌2💋2
⭐️ فعالسازی امکانات ویژه فیگما به صورت رایگان

فیگما یا Figma یکی از خفن‌ترین ابزارها برای طراحی رابط کاربری است که محبوبیت زیادی دارد. در فیگما می‌توانید حتی کاور پست‌های خودتون رو به ساده‌ترین روش ممکن طراحی کنید و یا انیمیشن بسازید!

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

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


⚠️هشدار

توجه داشته باشید که با فعالسازی اکانت به این روش، شما حق استفاده از فیگما برای بیزنس‌های خودتون رو نخواهید داشت! لذا در صورت استفاده بیزنسی احتمال مسدود شدن اکانتتان وجود دارد و به دلیل تحریم هم امکان درخواست فعالسازی مجدد اکانت وجود ندارد.
‌‌
چه اطلاعاتی نیاز هست؟
شما باید به عنوان دانش‌آموز، دانشجو یا مدرس درخواست را ارسال کنید. اما به دلیل تحریم ایران ممکن است اکانت شما به طور کل مسدود شود(تحریم دانشگاه‌های ایرانی). بنابراین در یودمی یا کورسرا دوره ui/ux یا آموزش فیگما که رایگان باشد را ببینید و بعد در صفحه درخواست گواهی پایان دوره رو ارسال کنید.

📎 Link: https://www.figma.com/education/


#Figma

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3❤‍🔥2
حق:
من این مشکل رو زیاد دیدم؛ بیش از حداقل 20% پروژه‌های خدماتی که دوستان روش کار می‌کنن. می‌بینم که Postgresql به معنای واقعی کلمه OverKill هست. مخصوصا وقتی Sqlite کار رو در میاره.

شاید به روی خودتون نیارید ولی خیلی از شما هم ازین پروژه‌ها دیدید دیگه.

خواستم هم اهمیت SQLite رو یادآوری کنم
هم بگم پروژه‌هایی مثل rqlite هم وجود داره‌ها

مثال:
کاری به درست و غلط بودن دیزاین و ... ندارم و بحثم فقط همین مورد Sqlite هست.
یک کدی رو دیدم؛ طرف یک سیستم verification جدا براش طراحی کرده بود و تمام پروژه‌هاشون ازین سرویس استفاده می‌کرد. فکر کنم این سرویس یا .net بود یا golang بعد بحث اصلی سر این بود که Postgres بذارند یا MsSql من درجا پیشنهاد SQlite رو دادم.
این دیتابیس خیلی اهمیت زیادی نداره؛ هر کد قراره نهایتا ۱۰ دقیقه valid باشه. در صورت پاک شدن هم طرف یکبار دیگه درخواست میده (که من تاحالا پاک شدن خود به خود توش ندیدم).

چرا می‌خواید شر درست کنید برای تیم devops, server, database, ...
خیلی ها مشکلشون این هست که اطلاعات ندارند (هیچ‌وقت هم جرات تجربه کردن نداشتند)؛ خود SQLite روی SSD طبق بنچمارک‌ها.
بیش از 500 هزار insert در ثانیه رو پشتیبانی می‌کنه و برای read هم این مورد به بیش از 1 میلیون میرسه و این مورد بدون config های پرفورمنسی هست که توی داکیومنت خودش ارائه شده.
روی NVMe هم چندسال قبل تست کردیم؛ اعداد بهتر هم میشه.

اضافه کنم :
اینم rqlite اگر حتی خواستید SQlite رو بصورت distributed داشته باشید (قبلا توی اون کی کانال راجبش صحبت کردم با   K8s )

Source
👍11❤‍🔥21👎1🔥1🥰1👌1💋1
چند نکته درباره وب سوکت و توضیح ساده برای درک بهتر

فرآیند ارتباط وب‌سوکت

1. شروع با HTTP/HTTPS:
- کلاینت ابتدا یک درخواست HTTP به سرور می‌فرستد. این درخواست شامل هدرهای خاصی است که نشان‌دهنده تمایل به ارتقاء ارتباط به وب‌سوکت است. این هدرها شامل موارد زیر هستند:
- Upgrade: websocket
- Connection: Upgrade

2. ارتقاء به وب‌سوکت:
- سرور درخواست را دریافت کرده و بررسی می‌کند. اگر شرایط درست باشد، با یک پاسخ خاص به کلاینت، ارتباط را به وب‌سوکت ارتقاء می‌دهد. این پاسخ شامل وضعیت 101 Switching Protocols است.

3. استفاده از ws:// و wss://:
- پس از ارتقاء، ارتباط به‌صورت دائمی و دوطرفه برقرار می‌شود.
- ws://
نشان‌دهنده استفاده از پروتکل وب‌سوکت بر روی HTTP است.
- wss://
نشان‌دهنده استفاده از پروتکل وب‌سوکت بر روی HTTPS است (که رمزنگاری شده است).

چرا ws:// استفاده می‌شود؟


- ws://localhost:8080
- این URL نشان می‌دهد که ارتباط نهایی به‌صورت وب‌سوکت انجام می‌شود.

نکته:
در HTTP/2، مکانیزم آپگرید به وب‌سوکت از طریق هدرهای HTTP/1.1 استفاده نمی‌شود. HTTP/2 به صورت ذاتی از این روش پشتیبانی نمی‌کند. برای ارتباط وب‌سوکت در HTTP/2، معمولاً از HTTP/1.1 برای ایجاد و ارتقاء ارتباط استفاده می‌شود یا از روش‌های دیگری برای مدیریت ارتباطات بلادرنگ بهره می‌گیرند.

روش‌های دیگه برای مدیریت ارتباطات بلادرنگ:
1. Server-Sent Events (SSE):
- یک ارتباط یک‌طرفه است که سرور می‌تواند به‌طور پیوسته داده‌ها را به کلاینت ارسال کند.
- مناسب برای برنامه‌هایی که نیاز به ارسال داده‌های بلادرنگ از سرور به کلاینت دارند.

2. Long Polling:
- کلاینت یک درخواست HTTP ارسال می‌کند و سرور تا زمانی که داده‌ای برای ارسال وجود ندارد، پاسخ را معلق نگه می‌دارد(یک تایم اوت مشخص هم دارد مثلا 20 ثانیه)
- پس از ارسال داده، کلاینت بلافاصله یک درخواست جدید ارسال می‌کند.

3. HTTP/2 Streams:
- استفاده از قابلیت چندپخشی و استریم‌های همزمان در HTTP/2 برای ارسال و دریافت داده‌های بلادرنگ.

4. gRPC:
- یک فریم‌ورک RPC بر پایه HTTP/2 که از ارتباطات بلادرنگ و استریمینگ پشتیبانی می‌کند.


چرا نیاز به درخواست HTTP اولیه است؟

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

مثال در گولنگ:
package main

import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
// checking conditions
return true
},
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
// upgrade http request to websocket
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return
}
defer ws.Close()

// messages
for {
messageType, msg, err := ws.ReadMessage()
if err != nil {
fmt.Println(err)
break
}
fmt.Printf("Received: %s\n", msg)

err = ws.WriteMessage(messageType, msg)
if err != nil {
fmt.Println(err)
break
}
}
}

func main() {
http.HandleFunc("/", handleConnections)
fmt.Println("Server started on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println("Error starting server:", err)
}
}

#websocket

@Syntax_fa
👍7💋6👌21