ลองจินตนาการสถานการณ์นี้: คุณเป็น Rails Developer ใช้ไปหลายวันพัฒนา Feature เก๋ๆ ที่ทุกคนรอคอย มันใหญ่และซับซ้อน แต่ผ่านการทดสอบอย่างเข้มงวด คุณมั่นใจว่าทุกอย่างทำงานได้ มี Deadline ต้อง respect จึง Deploy ทันที แล้วทุกอย่างพังทลาย
Feature ของคุณทำให้แอพพังสำหรับบาง User หาเหตุผลไม่ออก ไม่มี Bug ในช่วงทดสอบ คุณ Revert การเปลี่ยนแปลง แตความเสียหายเกิดขึ้นแล้ว ลูกค้าไม่พอใจ และคุณจะใช้เวลานานทำ Damage Control และสืบสวนว่าเกิดอะไรขึ้น
ปัญหาคือ การ Release การเปลี่ยนแปลงที่ซับซ้อนมีความเสี่ยงโดย जन्म แม้ทดสอบมากแค่ไหน ก็ดีถ้าคุณ Roll Out Feature นี้ค่อยๆ ไป ก็ต่อเมื่อไม่กี่ User ก่อน จะดีกว่านั้นถ้าคุณปิด Feature ทันทีเมื่อปัญหาแรกปรากฏ
นี่คือจุดที่ Feature Flags เข้ามาช่วย ในบทความนี้ เราจะเจาะลึก Feature Flags ใน Rails รวมถึงการ Setup ด้วย Gem Flipper แต่ก่อน: Feature Flags คืออะไร?
Feature Flags ใน Ruby on Rails คืออะไร?
Feature Flags เป็นวิธี Enable หรือ Disable Feature ในแอปพลิเคชันขณะที่มันกำลัง Run อยู่ หาก Flag Enabled Feature จะถูกใช้ มิฉะนั้นจะไม่ถูกใช้ จินตนาการ Pseudocode แบบนี้:
ชื่อ 'Feature Flag' ค่อนข้าง Misleading การควบคุมพฤติกรรมแอปขณะ Runtime ไม่ได้จำกัดแค่ Feature แต่วงได้กับ Function ใดๆ ในโปรแกรม คุณสามารถใช้ Feature Flags ลอง Performance Tweaks และรัน A/B Tests ได้ ต่างจาก Conditional ธรรมดาที่ Feature Flags สามารถ Modify ได้ขณะ Runtime
เพื่อการอธิบาย ลองจินตนาการ Mechanism Feature Flagging เรียบง่ายด้วย Environment Variables
ด้วยการเปลี่ยนค่า Environment Variable เราสามารถเปิด/ปิดส่วนต่างๆ ของแอปได้ตามต้องการ ส่วนไหนของแอป? อะไรก็ได้!
คุณสามารถซ่อนส่วนของ UI หาก Feature Disabled สลับส่วนของโค้ด ซึ่งมีประโยชน์มากหากคุณไม่มั่นใจใน Refactor ล่าสุด หนึ่งในการใช้งานโปรดของผมคือการซ่อน Route ทั้งหมดด้วย Routing Constraints:
เราเห็นแล้วว่ามี Application มากสำหรับ Feature Flags แต Implementation แบบ Naive ของเรามีจุดอ่อนสำคัญ Feature จะ On หรือ Off สำหรับทุก User
ถ้าอยาก Enable Feature แค่ User/Group เฉพาะ หรือแค่บางเวลา? มาดู Flipper
ใช้ Gem Flipper สำหรับ Feature Flags
Flipper เป็น Gem ที่ทำให้ Feature Flags และวิธี Toggle ต่างๆ พร้อมใช้ใน Rails มัน Modular มาก นอกจาก Gem หลัก คุณต้องเลือก Storage Adapter — แต่เรื่องนี้ภายหลัง ใช้ ActiveRecord Adapter ก่อน
เพิ่มบรรทัดนี้ใน Gemfile และรัน bundle install:
ตอนใช้ ActiveRecord Adapter Flipper จะเก็บ Feature Flag ใน Database จึงต้อง Setup Table ใหม่ Flipper มี Generator สะดวกสร้าง Migration ที่จำเป็น
คุณสามารถใช้ Flipper แบบเดียวกับ Naive Implementation ก่อนหน้า
ความต่างใหญ่คือแทนที่จะแก้ Environment Variables ตอนนี้คุณ Toggle Features ผ่าน UI ของ Flipper เพิ่ม Gem Flipper UI และติดตั้ง
แก้ไข Routes File เพื่อ Mount Flipper UI
Start แอปและไปที่ Flipper UI จะเห็น Overview ของ Features ทั้งหมดและ Status สร้าง Feature my_awesome_feature ได้เลย

Feature Toggles ใน Flipper
คุณสังเกตเห็นว่าใน Flipper UI ทำได้มากกว่าแค่ Enable/Disable Feature Flipper ให้ Enable Feature สำหรับ Subset ของ Users หรือ Percentage ของเวลา คุณ Config Feature Flags ได้ 5 Mechanism
หนึ่งคือ Boolean Toggle สวิตช์ On-Off ทั่วไป อีก 4 น่าสนใจกว่า:
Groups
เพื่อ Enable Feature สำหรับ Group User เฉพาะ ใช้ Group Toggle หากยังไม่มี สร้าง File config/initializers/flipper.rb และเพิ่มโค้ด Register Group ใหม่ — เช่น Paid Users
เพื่อใช้ Toggle ใหม่ แก้ Flipper Invocation ให้ส่ง User — หรือ Actor ตามเอกสาร — และ Feature Name
Flipper จะใช้ Block ที่ Define ใน Initializer 决定 Feature Enabled สำหรับ User นี้หรือไม่ ในกรณีนี้จะเรียกเมธอด paid? คุณสามารถใช้ Group นี้ใน Flipper UI กดปุ่ม 'Add a Group' และเลือก Group ของคุณ

Group ของคุณไม่จำเป็นต้องเป็น Paid Users อาจเป็นสมาชิกทีม หรือ User ที่สมัคร Beta Program การใช้ Group Toggle มีประโยชน์หากอยาก Release ให้ Subset ของ Users คิดถึง Beta Releases หรือ Internal Releases
Actors
บางครั้งอยาก Release ให้ Individual เดียว Actor Toggle คือสิ่งที่ควรพิจารณา
ไม่ต้องแก้ Initializer เพื่อใช้ Mechanism นี้ แต่ต้อง Ensure Actor Model (ส่วนใหญ่คือ User Model) Implement flipper_id การ Include Flipper::Identifier จัดการเรื่องนี้
คุณสามารถใช้ ID นี้ Enable Feature ให้ User เฉพาะราย

Feature Toggle นี้ Handy หากอยาก Preview Functionality ให้ Individual เฉพาะ คิดถึงการ Enable Test Accounts สำหรับ Partner ที่ต้องการ Access Feature ก่อน Release ให้กว้างขึ้น
Percentage of Actors
หากอยากเพิ่มการใช้ Feature แบบค่อยๆ Percentage of Actors Toggle คือคำตอบ จินตนาการว่า Implement Performance Optimization แล้ว แต่ไม่แน่ใจพฤติกรรมใน Production คุณ Roll Out ให้ Percentage เล็กของ Users ก่อน แล้วค่อยๆ เพิ่มขณะ Monitor แอป

ถ้าสิ่งเลวร้ายเกิดขึ้น คุณ Reset Percentage กลับเป็นศูนย์ได้ทุกเมื่อ
Percentage of Time
สุดท้าย คุณอาจ Enable Feature สำหรับ Percentage ของ Requests ไม่ต้อง Provide Actor เมื่อใช้ Toggle นี้
ผมชอบใช้เพื่อเปรียบเทียบ Performance ของ Implementation 2 แบบ โปรดทราบ Feature Toggle นี้เป็น Random User เดียวกันจะได้พฤติกรรมต่างกันทุก Request
Advanced Configuration ใน Flipper
เราเห็นแล้วว่าสามารถใช้ ActiveRecord Adapter เก็บ Feature Flag ใน Database แต่ขึ้นกับความต้องการ คุณอาจอยาก Adapter อื่น
ส่วนใหญ่ตอน Swap Storage Adapter แค่ Install Gem นั้นและ Config Flipper ใหม่ เช่นอยากใช้ Redis Adapter เพิ่ม Gem flipper-redis ใน Gemfile และ Update Flipper Initializer
นอกจาก Config Storage Adapters ยังมีมากมายของ Flipper ที่ปรับแต่งได้
การเพิ่ม Feature Flags มี Performance Penalty เล็กน้อย ดังนั้นคุณมักจะอยากเพิ่ม Memoization และ Caching คุณน่าจะอยาก Restrict Access ให้ Flipper UI แค่ Authorized Users หัวข้อนี้อยู่นอกขอบเขตบทความ แต่อยากลึกลึกกว่านี้ อ่าน Flipper Documentation
Caveats ของ Feature Flags ใน Rails
Feature Flags ดีมาก แต่เหมือนหลายอย่าง มี Tradeoffs ที่ต้องคิด
การเพิ่มและ Maintain Feature Flags เพิ่ม Organizational Overhead การ Release และ Roll Out Hidden Features ด้วย Flags ไม่ง่ายเท่า Deploy 'Regular' Code — คุณต้องจดจำที่จะเปิดมัน! นั้นมักไม่ยาก แต่ Clean Up Feature Flags ที่ไม่ต้องแล้วอาจยาก
ทุกครั้งที่เพิ่ม Feature Flag ในโค้ด คุณเพิ่ม Conditional และถ้าไม่ระวัง โค้ดจะเต็มไปด้วยมัน การติดตามเมื่อไหร่และทำไมสร้าง Feature Flags บางตัวอาจท้าทาย น่าเสียดาย Flipper UI เองไม่เสนอเครื่องมือมากสำหรับ Manage Feature Flags
คุณควรทราบว่าการใช้ Feature Flags จะมี Minor Performance Penalty มีวิธี Mitigate แต่อาจมี Impact เห็นได้ชัดหาก Misconfigure หรือ Misuse Flipper
สรุป: เริ่มต้น Feature Flags ใน Ruby on Rails
เราดูว่า Feature Flags ช่วย Release ด้วยความมั่นใจมากขึ้น เรียนรู้การทำงานใน Principle และเห็นวิธีเริ่มต้นด้วย Gem Flipper
มีสถานการณ์มากที่ Feature Flags Handy ขึ้นกับ Use Case คุณอาจใช้ 5 Toggle ต่างๆ — Boolean, Group, Actor, Percentage of Actors, หรือ Percentage of Requests
แม้การทำงานกับ Feature Flags มี Caveats และอาจใช้เวลาปรับตัว แต่ก็เป็น Tool ยอดเยี่ยมที่ควรมีในมือ
จนกว่าจะเจอกันใหม่ Happy Coding!
P.S. หากต้องการอ่านบทความ Ruby Magic ทันทีที่เผยแพร่ สมัคร Newsletter Ruby Magic ของเราและจะไม่พลาดบทความเด็ดๆ ไป!