برنامه نویسی

😴 کد بروید که می توانید به آن اعتماد کنید: بعد از تعهد خوب بخوابید

بعد از ظهر جمعه ، ساعت 4:45 بعد از ظهر است. هم تیمی های من در حال بحث در مورد برنامه های آخر هفته در Slack هستند. من یک قطعه مهم از سرویس پردازش پرداخت خود را به پایان می رسانم. کد انجام شده است ، تست ها می گذرد ، و من قصد دارم قبل از رفتن به آخر هفته ، آن را مرتکب شوم. انگشت من برای لحظه ای روی کلید enter معلق است …

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

این همیشه اینگونه نبود. ده سال پیش ، من تمام آخر هفته تلفن خود را چک می کردم ، و نگران تماس 3 صبح از مهندس تماس با ما بود.

چه چیزی تغییر کرد؟ بگذارید داستان خود را در مورد چگونگی یادگیری نوشتن کد GO برای شما تعریف کنم که می توانم کاملاً به آن اعتماد کنم.

گلانگ خواب
منبع تصویر: متوسط

هزینه کد نامشخص

سفر من با GO از سال 2021 هنگامی که من در یک راه اندازی به سرعت در حال رشد کار می کردم ، آغاز شد. ما از یک برنامه جاوا یکپارچه به سمت میکروسرویس حرکت می کردیم ، و به نظر می رسید که مناسب است: سریع ، ساده و با همزمانی داخلی.

اما کد اولیه من به این شکل بود:

func ProcessPayment(paymentID string) error {
    // Get payment details
    payment, err := db.GetPayment(paymentID)
    if err != nil {
        return err // Which error? What happened?
    }

    // Process the payment
    err = paymentGateway.Process(payment)
    if err != nil {
        return err // Again, what went wrong?
    }

    // Update payment status
    err = db.UpdateStatus(paymentID, "processed")
    if err != nil {
        return err // Did the payment go through? Is it in a bad state?
    }

    return nil
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از نظر عملکردی ، این کد کار کرد. اما شبانه مرا آزار داد زیرا:

  1. رسیدگی به خطا حداقل بود و هیچ زمینه ای ارائه نمی داد
  2. برای اشکال زدایی هیچ ورود به سیستم وجود نداشت
  3. در مورد خرابی های جزئی در نظر نمی گیرد
  4. بدون اعتبار ورودی
  5. بدون آزمایش برای موارد لبه

نتیجه؟ بلیط های صبح شنبه را پشتیبانی کنید. خرابی های مرموز پرداخت. ساعاتی که در جلسات اشکال زدایی صرف می شود. و اضطراب مداوم که ممکن است چیزی بی صدا باشد.

مسیر کد قابل اعتماد

وقتی به تیم WF پیوستم ، همه چیز تغییر کرد. مربی من یک فلسفه ساده داشت: “هر خط کد را بنویسید که گویی هنگام تولید در تعطیلات خواهید بود.”

این تغییر ذهنیت نحوه نزدیک شدن به توسعه GO را تغییر داد. این چیزی است که من آموخته ام ، و آنچه اکنون به من اجازه می دهد بعد از ارتکاب کد خوب بخوابم:

1. خطاها دوستان شما هستند ، نه استثنا

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

func ProcessPayment(paymentID string) error {
    // Get payment details
    payment, err := db.GetPayment(paymentID)
    if err != nil {
        return fmt.Errorf("failed to retrieve payment %s: %w", paymentID, err)
    }

    // Validate before proceeding
    if err := validatePayment(payment); err != nil {
        return fmt.Errorf("payment validation failed for %s: %w", paymentID, err)
    }

    // Process the payment with context
    err = paymentGateway.Process(payment)
    if err != nil {
        // Log additional details for debugging
        log.WithFields(log.Fields{
            "payment_id": paymentID,
            "amount":     payment.Amount,
            "currency":   payment.Currency,
        }).Error("Payment processing failed")

        return fmt.Errorf("gateway failed to process payment %s: %w", paymentID, err)
    }

    // Success path is clearly logged too
    log.WithField("payment_id", paymentID).Info("Payment processed successfully")
    return nil
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

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

2. تست هایی که به شما اطمینان می دهد

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

func TestProcessPayment(t *testing.T) {
    // Happy path test
    t.Run("successful payment processing", func(t *testing.T) {
        // Setup and assertions
    })

    // What happens when things go wrong
    t.Run("database unavailable", func(t *testing.T) {
        // Simulate DB failure
    })

    t.Run("payment gateway timeout", func(t *testing.T) {
        // Simulate slow payment gateway
    })

    t.Run("invalid payment data", func(t *testing.T) {
        // Test validation logic
    })

    t.Run("partial failure - payment processed but status update fails", func(t *testing.T) {
        // Test recovery mechanisms
    })
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

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

3. تخریب برازنده

یک بینش کلیدی: همه شکست ها برابر نیستند. بهترین کد GO فقط خطاها را تحمل نمی کند. این قابلیت عملکرد را به طرز فجیعی تخریب می کند:

func GetUserRecommendations(userID string) ([]Recommendation, error) {
    // Try to get personalized recommendations
    recommendations, err := recommendationService.GetPersonalized(userID)
    if err != nil {
        // Log the error
        log.WithError(err).Warn("Failed to get personalized recommendations, falling back to popular items")

        // Fall back to popular recommendations
        return recommendationService.GetPopular()
    }

    return recommendations, nil
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این الگوی به این معنی است که کد شما تمام تلاش خود را برای ارائه ارزش می کند ، حتی اگر برخی از مؤلفه ها شکست بخورند.

4. نظارت و مشاهده داخلی

کدی که من می توانم به آن اعتماد کنم فقط خوب کار نمی کند. این به من می گوید که چگونه کار می کند:

func ProcessOrder(ctx context.Context, order Order) error {
    // Start timing the operation
    start := time.Now()

    // Use defer to ensure metrics are always recorded
    defer func() {
        metrics.ObserveOrderProcessingTime(time.Since(start))
        metrics.IncrementOrdersProcessed()
    }()

    // Trace this operation for distributed tracing
    span, ctx := tracer.StartSpanFromContext(ctx, "process_order")
    defer span.Finish()

    // Add helpful information to the trace
    span.SetTag("order_id", order.ID)
    span.SetTag("customer_id", order.CustomerID)

    // Process the order with the traced context
    if err := orderProcessor.Process(ctx, order); err != nil {
        // Record error in metrics and trace
        metrics.IncrementOrderErrors()
        span.SetTag("error", true)
        span.LogKV("error.message", err.Error())

        return fmt.Errorf("processing order %s failed: %w", order.ID, err)
    }

    return nil
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

هنگامی که کد شما نظارت داخلی دارد ، نیازی به تعجب نیست که آیا به درستی در تولید کار می کند. شما دانستنبشر

مثال واقعی زندگی: اشکال 3 صبح که هرگز صدا نمی زد

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

مطمئناً ، اتفاق غیر منتظره ای رخ داده است: یک API شخص ثالث که ما به تغییر قالب پاسخ آنها وابسته بودیم. اما به جای قطع تولید ، آنچه اتفاق افتاده است:

  1. اعتبار سنجی ما قالب تغییر یافته را گرفت و یک خطای واضح را برگرداند
  2. قطع کننده مدار که ما اجرا کردیم از خرابی های آبشار جلوگیری کرد
  3. این سیستم به یک روش پردازش ثانویه بازگشت
  4. نظارت ما با مسئله دقیق مهندس تماس را هشدار داد
  5. سیاهههای مربوطه دقیقاً نشان می دهد که در کجا و چگونه قالب تغییر کرده است

مهندس تماس با یک تغییر پیکربندی ساده آن را برطرف کرد-بدون اضطراری ، بدون جلسه اشکال زدایی همه دست.

بهترین قسمت؟ من فقط در مورد این موضوع فهمیدم که گزارش حادثه را صبح سه شنبه خواندم.

نحوه نوشتن کد GO که می توانید به آن اعتماد کنید

بعد از گذشت یک دهه از نوشتن ، لیست چک من برای کد است که می توانم به اندازه کافی اعتماد کنم تا کاملاً از کار جدا شوم:

  1. خطاها را با متن انجام دهید: خطاها را بپیچید ، اطلاعات را اضافه کنید ، اشکال زدایی را آسان کنید
  2. حالت های خرابی آزمون: فقط موارد موفقیت را آزمایش نکنید. آنچه را که اتفاق می افتد آزمایش کنید
  3. با تخریب برازنده بسازید: سیستم های طراحی که به جای شکسته شدن خم می شوند
  4. آن را قابل مشاهده کنید: ورود به سیستم ، معیارها و ردیابی
  5. تأیید زود هنگام و کامل: قبل از ایجاد آسیب ، ورودی های بد را بگیرید
  6. فرضیات مستند: مستندات پاک به شما و هم تیمی های خود کمک می کند

پایان

تفاوت بین کد GO که شما را در شب و کد GO که می توانید به آن اعتماد کنید ، مربوط به الگوریتم های هوشمندانه یا ویژگی های پیشرفته نیست. این مربوط به مراقبت ، توجه به جزئیات و طرز فکر است که برای غیر منتظره آماده می شود.

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

از آنجا که در پایان ، بهترین کد فقط از لحاظ عملکردی صحیح نیست – به اندازه کافی قابل اعتماد است که می توانید آن را در بعد از ظهر جمعه انجام دهید و تا صبح دوشنبه واقعاً قطع شوید.

و برای من ، که آرامش ذهن ارزش هر خط اضافی برای خطای ، هر مورد آزمایش اضافی را دارد و هر دقیقه که می توانم کد من را قوی تر کنم.

بنابراین دفعه بعد که می نویسید کد GO را می نویسید ، از خود بپرسید: “اگر بعد از ترک من این کار را اجرا کرد ، امشب خوب می خوابم؟” اگر جواب اعتماد به نفس “بله” نیست ، شما کارهای بیشتری برای انجام دادن دارید.

خود آینده شما – احتمالاً در یک ساحل در جایی بدون دسترسی به لپ تاپ – از شما متشکرم.

نوشته های مشابه

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا