
صف همگامسازی که کسی دربارهاش حرف نمیزند: صندوق فروش آفلاین چطور دو کشوی پول را با هم تطبیق میدهد
ما سازندهی Pultrack هستیم، یک اپلیکیشن صندوق فروش و مدیریت موجودی برای خردهفروشان کوچکی که با قطعی برق نامنظم، اینترنت ضعیف و اغلب دو ارز روی یک قفسه سر و کار دارند. پس وقتی موجی از مقالههای فنی دربارهی «صندوق فروش آفلاینمحور» منتشر میشود، ما آنها را نه بهعنوان نمودارهای معماری، بلکه با این پرسش میخوانیم که سهشنبهای که شبکه در وسط یک شیفت قطع میشود و دو نفر همچنان دارند برای مشتریها حساب میکنند، واقعاً چه اتفاقی میافتد.
واقعاً چه چیزی در گفتگوی «آفلاینمحور» جدید است؟
مجموعهی اخیر مقالات فنی دربارهی طراحی صندوق فروش آفلاینمحور بر یک نکته توافق دارند: کارکرد آفلاین دیگر یک حالت استثنایی برای وصلهکاری نیست، بلکه پیشفرض اولیهی کل سیستم است.[۱] پیادهسازیها همگی به سمت یک پشتهی آشنا همگرا میشوند — یک پایگاهداده محلی روی دستگاه (IndexedDB یا SQLite)، صفی از عملیات در انتظار، رابطهای برنامهنویسی همگامسازی ایدمپوتنت (idempotent)، و نوعی حل تعارض وقتی اتصال برمیگردد.[۱] چند صفحهی محصولات فروشندگان این موضوع را کمتر بهعنوان یک جزئیات فنی و بیشتر بهعنوان یک تعهد کسبوکاری معرفی میکنند: صندوق همچنان کار میکند، پس مغازه همچنان درآمد کسب میکند، حتی وقتی اینترنت همکاری نمیکند.[۲] این چارچوببندی مفید و تا حد زیادی درست است. اما تقریباً هیچکدام از مطالب عمومی زمان واقعی را روی بخشی صرف نمیکنند که در نهایت تعیین میکند آیا یک مغازهی کوچک بعداً به سیستم اعتماد میکند یا نه: اینکه در ثانیهها و دقایق درست پس از اتصال دوبارهی دو دستگاه آفلاین چه اتفاقی میافتد، وقتی هر دو ادعا میکنند همان کالا را فروختهاند، به همان مشتری پول برگرداندهاند، یا همان شیفت را بستهاند.
چرا حتی یک مغازه با یک صندوق هم به این مشکل برمیخورد؟
وسوسهانگیز است که فکر کنیم تعارضهای تطبیق حساب فقط مشکل «چند شعبهای» یا «سازمانی» است. اینطور نیست. یک مغازهی سر کوچه به محض اینکه بیش از یک راه برای ثبت فروش در حالت آفلاین داشته باشد — یک گوشی روی پیشخوان و یک تبلت کنار انبار، دستگاه صندوقدار و دستگاه صاحب مغازه، یا حتی همان یک دستگاه که بعد از قطع برق در وسط همگامسازی دوباره راهاندازی شده — به این مشکل برمیخورد. هرکدام از اینها یک «گره» جداگانه به آن معنایی است که در طراحیهای آفلاینمحور واقعی به کار میرود، و هر کدام نوشتههای محلی خودش را در صف میگذارد تا بتواند دوباره با سرور صحبت کند.[۱] الگوی معماری این مسئله را با صفهای همگامسازی و عملیات ایدمپوتنت حل میکند تا تکرار یک عملیات دوبار، باعث دو بار برداشت پول یا کسر موجودی نشود.[۱] این پاسخ مهندسی درستی است. اما پرسش خردهفروشی چیز دیگری است: وقتی همان شیفت فیزیکی دو نسخهی محلی «درست» از رویدادها تولید میکند — مثلاً یک تخفیف که روی یک دستگاه اعمال شده و فروش تمامقیمت همان کالا که روی دستگاه دیگری ثبت شده — کدام نسخه در جمع کل روزانهی مغازه منعکس میشود، و آیا مغازهدار پیش یا پس از اینکه پول کشوی صندوق را تطبیق داده، از این موضوع باخبر میشود؟
«تداوم درآمد» چه چیزی را نادیده میگیرد؟
فروشندگان بهطور فزایندهای قابلیت آفلاین را در قالب تداوم درآمد توصیف میکنند: صندوق فقط به این دلیل که شبکه از کار افتاده، فروش را متوقف نمیکند.[۳] این ادعای منصفانه و مهمی است، بهویژه برای بازارهایی که قطعی اتصال در آنها یک امر روتین است، نه استثنا. اما تداوم درآمد در طول قطعی فقط نیمی از داستان است. نیمهی دیگر، دقتِ تطبیق حساب پس از قطعی است — اینکه آیا مجموع اعدادی که در نهایت با سیستم مرجع همگامسازی میشوند، با آنچه واقعاً پشت پیشخوان اتفاق افتاده، کالا به کالا و ارز به ارز، مطابقت دارند یا نه. برای مغازهای که دو ارز را کنار هم اداره میکند، این موضوع اهمیت بیشتری دارد، نه کمتر. یک فروش آفلاین که با نرخ ارز محلی ثبت شده و ساعتها بعد، پس از تغییر نرخ، همگامسازی میشود، شکافی کوچک اما واقعی بین آنچه روی قفسه نوشته شده و آنچه اکنون در دفاتر نشان داده میشود ایجاد میکند. هیچکدام از مقالات عمومی دربارهی آفلاینمحور که ما بررسی کردیم، بهطور خاص به تطبیق حساب چندارزی نپرداختهاند — و این خلأیی است که ارزش نام بردن دارد، نه پوشاندن.
آیا «محلیمحور» همان «ایمن در برابر تطبیق حساب» است؟
نه لزوماً. استدلال گستردهتر در مطالب فعلی دربارهی آفلاینمحور این است که فروشندگان کوچک به «صندوق فروش ابری با حالت آفلاین» نیاز ندارند — آنها به زیرساخت تجاریای نیاز دارند که در آن اینترنت بهعنوان یک کانال همگامسازی در نظر گرفته شود، نه یک وابستگی.[۴] این یک اصل طراحی درست است و شیوهی صحیح تفکر دربارهی اتصال به شبکه است. اما «محلیمحور» توصیف میکند داده کجا زندگی میکند و چگونه ثبت میشود؛ به خودی خود تضمین نمیکند که دو حقیقت محلی به یک جمع کل صحیح برای شیفت تبدیل شوند. منطق حل تعارض — آخریننوشتهبرنده، صف بازبینی دستی، یا بازپخش رویدادمحور — یک انتخاب طراحی با مصالحههای واقعی است، و همین بخش تعیین میکند که آیا مغازهدار میتواند به عددی که هنگام بستن صندوق روی صفحه میبیند اعتماد کند یا نه. چند الگوی عملی که در عمل «توانایی کار آفلاین» را از «ایمن در برابر تطبیق حساب» جدا میکنند:
- هر تراکنش آفلاین پیش از قرار گرفتن در صف، یک شناسهی یکتای پایدار و تولیدشده روی همان دستگاه میگیرد، تا بازپخش یا همگامسازی تکراری هرگز باعث شمارش دوبارهی آن نشود.
- تعارضها به یک انسان نشان داده میشوند — حتی یک اعلان ساده مثل «این دو رکورد با هم مغایرت دارند، یکی را انتخاب کن» — به جای اینکه بهطور خاموش با تشخیص آخرین دستگاهی که همگامسازی شده، حل شوند.
- مقادیر ارز و نرخ تبدیل در لحظهی فروش قفل میشوند، نه اینکه در زمان همگامسازی دوباره محاسبه شوند، تا یک همگامسازی دیرهنگام مقدار گزارششدهی یک شیفت را بیسروصدا تغییر ندهد.
- جمع کل شیفت از روی کل گزارش رویدادها بازسازی میشود، نه فقط از روی آخرین وضعیت شناختهشده، تا در بازبینی دقیقاً مشخص شود کدام دستگاه چه چیزی را کِی ثبت کرده است.
یک مغازهی کوچک چطور باید این موضوع را پیش از خرید ارزیابی کند؟
از آنجا که بیشتر آنچه دربارهی این موضوع منتشر شده از بلاگهای فروشندگان، مطالعات موردی مهندسی و صفحات بازاریابی محصول میآید، نه از ممیزیهای مستقل، ارزش دارد که برچسب «آفلاینمحور» را بیشتر یک اصطلاح بازاریابی در نظر بگیریم تا یک تضمین. معماری زیربنایی — ذخیرهسازی محلی، صفهای همگامسازی، رابطهای برنامهنویسی ایدمپوتنت — واقعاً در میان محصولات مختلف در حال همگرایی است.[۱] چیزی که تفاوت زیادی دارد، و بهندرت بهطور عمومی مستند میشود، این است که هر فروشنده با بخش شلوغ میانی چطور برخورد میکند: تعارضهای چنددستگاهی، انحراف نرخ ارز در طول تأخیر همگامسازی، و اینکه آیا مغازهدار واقعاً میتواند یک تراکنش مورد اختلاف را ببیند و اصلاح کند یا فقط باید به جمع کل اعتماد کند. در Pultrack، این همان بخشی است که بیشترین زمان مهندسی را روی آن صرف میکنیم، دقیقاً چون وقتی درست کار میکند نامرئی است و وقتی درست کار نکند، پرهزینه: هر فروش آفلاین برچسب زمانی، مبدأ دستگاه و نرخ ارز قفلشدهی خودش را همراه دارد، و رکوردهای متعارض برای بازبینی نمایش داده میشوند به جای اینکه بیصدا یکدیگر را بازنویسی کنند. ما فکر میکنیم این روش صادقانهتری برای صحبت دربارهی تابآوری آفلاین است — نه فقط «همچنان میفروشد»، بلکه «بعد از آن هم درست میشمارد». اگر در حال مقایسهی گزینههای صندوق فروش آفلاینمحور هستید، پرسشهایی که ارزش پرسیدن از فروشنده را دارند دربارهی ادعاهای زمان کارکرد نیستند. آنها دربارهی این هستند که چه اتفاقی برای اعداد شما میافتد، درست همان لحظهای که دو دستگاهی که هر دو آفلاین بودهاند، همزمان دوباره آنلاین میشوند.