Web appOpen in Telegram

Threadدرود دوستان

12 messages · –
-
Photo
click to show
درود دوستان درحال کار روی یه پروژه هستم که fastapi و یه ربات تلگرامی باهم اجرا میشن. عملیات ها هم همگی توی لایه service انجام میشن سوالم اینه که آیا بهتره هنگامی که یه سشن دیتابیس باز میکنم همیشه توی transaction باشه یا صرفا جاهایی که میخوام write کنم بازش کنم؟ یه نگاه به عکس بکنید. این یه متد از سرویسم هست. توی حالت فعلی (استفاده همیشگی از tx) سشن دیتابیس خارج از سرویس ایجاد میشه و پاس داده میشه به سرویس. پس داخل سرویس من نمیدونم که کامیت انجام میشه یا نه. چون ممکنه بعدش عملیات های دیگه ای قرار بگیرن و اگر اونا به ارور بخورن کل operation رولبک میشه. یا فرضا توی همین عکس جایی که من TODO گذاشتم رو نگاه کنید. اینجا من میخوام یه نوتیفیکیشنی ارسال کنم که ارور خوردنش لزومی نداره رولبک کنه. مشکلات دیگه ای که ممکنه بر بخورم سمت handler های تلگرام هست. اینجا چون با io سرکار داریم اگر بخوام به ازای هر اپدیتی که میاد و تا handle شدن کامل اون توسط handler من tx رو باز بذارم توی بعضی حالات ممکنه ۱ تا ۲ ثانیه زمان بر باشه. یا اصلا بخاطر ارتباط با سرور های تلگرام تایم اوت بخورم. اینطوری کل عملیات رولبک میشه.
  1. S
    من تو موقعیت مشابه یه رویکردی داشتم، یه تابع واسه پروسه ارسال نوتیف نوشتم و اونو با asyncio.create_task اجرا کردم که در واقعا به صورت fire and forget انجام دادم. برای من مهم نبود که قطعا نوتیف ارسال بشه یا نه چون نهایتا کاربر تاثیرش رو میدید، برام مهم بود که داخل سشن دیتابیس ام ارور تلگرامی باعث رولبک نشه
    1. -
      اره این راه تو ذهن خودمم هست. اما این فقط برای همین سناریو که توی عکس هسته ممکنه حالت های دیگه ای هم وجود داشته باشه مثلا: یه همچین کدی دارم توی router. که services رو اینجکت کرده. و خود services هم db_session رو اینجکت کرده ... services.checkout.pay() services.invoices.get() ... اگر توی لاین دوم یا هر لاین کدی بعد از pay من به ارور بخورم. کل اون operation رولبک میشه که شاید اصلا خط کد های بعدی اونقدی مهم نباشن. حالا این قضیه توی handler های سمت ربات تلگرام هم صادقه.
      1. S
        الان سرویس های تو خودشون سشن دیتابیس میسازن یا همیشه از caller میگیرن سشن رو؟
        1. -
          همیشه از کالر میگیرن سمت fastapi یه همچین چیزی دارم async def db_session() -> AsyncGenerator[AsyncSession]: async with session_scope() as session: yield session SessionDep = Annotated[AsyncSession, Depends(db_session)] def get_services(session: SessionDep, redis: RedisDep) -> Services: return Services(session, redis) ServicesDep = Annotated[Services, Depends(get_services)] async def router(services: ServicesDep, ....): services.checkout.pay(...) که همین متدی که شات دادم میشه سمت تلگرام هنوز کدش رو نزدم اما مشابهه همین میشه. برای هر handler اینجکت میشه
          1. S
            اگر transaction بودن یک session برات تا checkout.pay مهم هستش، یک رویکرد اینه که بعد checkout.pay یکبار سشن رو کامیت کنی فقط کامیت رو در اختیار خود سرویس نزار و تو لایه caller اینکار رو انجام بده
  2. X
    وقتی از session استفاده میکنید در هرصورت transaction ایجاد میشه. فرقی برای read و write نداره‌. اگه begin رو کال نکنید خود sqlalchemy این کارو میکنه چون رفتار سشن به صورت دیفالت autobegin=true هست.
  3. X
    نوتیفیکشن رو نباید از لایه سرویس ارسال کنید‌. باید لایه orchestration رو به برنامتون اضافه کنید. یک usecase میخواید که متود های سرویس رو کال کنه. من همیشه session رو در usecase begin میکنم تا پترن uow رو رعایت بشه
    1. -
      Link
      click to show
      ممنون از وقتی که گذاشتید https://t.me/PythonFellow/75316 این پیامم رو بخونید. صرفا راجب ارسال نوتیفیکیشن نیست. اگر کلا هروقت سشنی باز میکنم begin استفاده کنم. یعنی از همون ابتدای باز کردن سشن. یعنی کل route و تمام پروسه های داخلش وارد tx میشه. حالا اگر هر کدی توی هر قسمت اروری بده که شاید مهمم نباشه. کل فرایند رولبک میشه. پس پیشنهاد شما اینه که صرفا جایی که نیاز هست کامیت کنم
    2. -
      اما طبق حرف خودتون. حتی اگر begin رو کال نکنم با اولین سلکت implicit begin میشه حالا وقتی داخل کد من دوباره بیام begin کنم. مثل همون شاتی که دادم. اونجا ارور میخورم که از قبل داخل tx هستی این مشکل رو چیکار کنم؟
      1. X
        باید از begin nested استفاده کنید. اتفاقا چندتا سناریوی مشابه داشتم. راه حلی استفاده کردم برسی کنم میفرستم
        1. -
          بله اما نکته ای که هست اینه ک به هر حال باید outer tx هم کامیت بشه تا inner هم بشه
PPython Backend FellowPython Backend Fellow@PythonFellow · group · Tech
1 290members52writing in 30 days
Venue feed Open in Telegram

An open public feed from the search index ChatCrawler — “Google for public Telegram”; refreshed as the venue is crawled. Times are UTC.

Public content only, official Telegram API. About · FAQ · What we do not do · Remove a page · Catalog · Search · How we count