फ़ीचर फ़्लैग और कैनरी मोड

Media3 में, इसकी सभी लाइब्रेरी के लिए नए ऑप्टिमाइज़ेशन, व्यवहार में सुधार, और आर्किटेक्चर में सुधार किए गए हैं. इन बदलावों को रिलीज़ करने से पहले, इनकी अच्छी तरह से जांच और पुष्टि की जाती है. हालांकि, Media3 में एक सेंट्रलाइज़्ड फ़ीचर फ़्लैग इन्फ़्रास्ट्रक्चर (androidx.media3.common.Flags) शामिल है. यह Canary मोड पर आधारित है. इससे ऐप्लिकेशन को यह कंट्रोल मिलता है कि नए व्यवहारों को कैसे और कब अपनाया जाए.

इस पेज पर बताया गया है कि कैनरी मोड और फ़ीचर फ़्लैग कैसे काम करते हैं. साथ ही, इन्हें अपने ऐप्लिकेशन में इस्तेमाल करने का तरीका भी बताया गया है. इनकी मदद से, रिलीज़ के दौरान अपग्रेड से जुड़े जोखिमों को कम किया जा सकता है, कंट्रोल किए गए रोलआउट चलाए जा सकते हैं, और इमरजेंसी रोलबैक कॉन्फ़िगर किए जा सकते हैं.

खास जानकारी

Canary मोड, लाइब्रेरी में किए गए नए और पुष्टि किए गए सुधारों को एक ही ग्लोबल टॉगल के तहत ग्रुप करता है:

  • डिफ़ॉल्ट रूप से चालू: Media3 की स्टैंडर्ड रिलीज़ में, कैनरी मोड डिफ़ॉल्ट रूप से चालू होता है (true). इससे यह पक्का होता है कि आपके ऐप्लिकेशन को सुरक्षित तरीके से परफ़ॉर्मेंस को बेहतर बनाने, ऑप्टिमाइज़ेशन, और नई सुविधाओं का फ़ायदा अपने-आप मिले.
  • ऑप्ट-आउट और रोलबैक करने की सुविधा: ऐप्लिकेशन, कैनरी मोड को दुनिया भर में बंद कर सकते हैं या रनटाइम के दौरान, कुछ फ़ीचर फ़्लैग को अलग से बदल सकते हैं.
  • वायरिंग की कोई जटिलता नहीं: फ़्लैग को common मॉड्यूल में मौजूद, सेंट्रल Flags क्लास के ज़रिए मैनेज किया जाता है. इससे अलग-अलग कॉम्पोनेंट के लिए, खास सेटर या कॉन्फ़िगरेशन ऑब्जेक्ट की ज़रूरत नहीं पड़ती.

अपने ऐप्लिकेशन में फ़्लैग का इस्तेमाल क्यों करें?

कैनरी मोड डिफ़ॉल्ट रूप से चालू रहता है. हालांकि, Flags को अपने ऐप्लिकेशन के कॉन्फ़िगरेशन या एक्सपेरिमेंट फ़्रेमवर्क के साथ इंटिग्रेट करने से कई फ़ायदे मिलते हैं:

1. वर्शन अपग्रेड करने से जुड़े जोखिम को कम करना

प्रोडक्शन में लाइब्रेरी के मेजर या माइनर वर्शन को अपग्रेड करने से, कुछ ओईएम डिवाइसों या कस्टम मीडिया पाइपलाइन पर अनचाहे इंटरैक्शन हो सकते हैं. Media3 को अपडेट करते समय, कैनरी मोड और रिमोट कॉन्फ़िगरेशन का इस्तेमाल किया जा सकता है. इससे सभी रिलीज़ में, अपग्रेड करने की प्रोसेस ज़्यादा सुरक्षित हो जाती है:

  1. कैनरी मोड बंद करके अपडेट शिप करना: कैनरी मोड बंद करके Media3 का नया वर्शन रिलीज़ करने से, पिछली रिलीज़ (कैनरी मोड चालू होने पर) के फ़ीचर सेट को करीब-करीब सुरक्षित रखा जाता है. इससे, नए व्यवहारों को अपनाने से पहले, प्रोडक्शन में बेसलाइन लाइब्रेरी की स्थिरता और सामान्य गड़बड़ियों को ठीक करने की पुष्टि की जा सकती है.
  2. कैनरी मोड को धीरे-धीरे चालू करें: रिमोट कॉन्फ़िगरेशन का इस्तेमाल करके, उपयोगकर्ताओं के अलग-अलग ग्रुप के लिए कैनरी मोड को चरणों में चालू करें. उदाहरण के लिए, 5% → 25% → 100%. इसके अलावा, मेट्रिक पर पड़ने वाले असर को मेज़र करने के लिए, A/B एक्सपेरिमेंट चलाएं.
  3. ज़रूरत पड़ने पर रोल बैक करना: अगर कुछ डिवाइसों पर रिग्रेशन होता है, तो ऐप्लिकेशन को इमरजेंसी में रिलीज़ किए बिना, कैनरी मोड या फ़्लैग आईडी को रिमोटली बंद किया जा सकता है.
  4. डिफ़ॉल्ट के तौर पर अपनाएं: पुष्टि होने के बाद, Canary मोड को डिफ़ॉल्ट रूप से तब तक चालू रखें, जब तक कि अगला वर्शन अपग्रेड न हो जाए. इसके बाद, Canary की जिन सुविधाओं की पुष्टि पहले की गई थी वे स्थायी हो जाएंगी.

Kotlin

// Enable or disable Canary mode globally (defaults to true).
Flags.setCanaryModeEnabled(false)

Java

// Enable or disable Canary mode globally (defaults to true).
Flags.setCanaryModeEnabled(false);

2. कंट्रोल की गई कुछ-कुछ उपयोगकर्ताओं के लिए रिलीज़ और A/B टेस्टिंग

अपने सभी उपयोगकर्ताओं को एक साथ नई लाइब्रेरी के व्यवहार दिखाने के बजाय, Flags को रिमोट कॉन्फ़िगरेशन या एक्सपेरिमेंट सिस्टम से कनेक्ट किया जा सकता है.

कैनरी मोड को चरणों में चालू किया जा सकता है. उदाहरण के लिए, 5% उपयोगकर्ता → 25% → 100%. इसके अलावा, A/B एक्सपेरिमेंट चलाकर, वीडियो चलाने से जुड़ी मुख्य मेट्रिक पर नए ऑप्टिमाइज़ेशन के असर का आकलन किया जा सकता है. जैसे, स्टार्टअप लेटेंसी, रीबफ़र रेट, और वीडियो चलाने में आने वाली गड़बड़ियां.

3. रिमोट किल स्विच और रैपिड रोलबैक

अगर किसी डिवाइस मॉडल या ओएस वर्शन पर प्रोडक्शन में रिग्रेशन होता है, तो सर्वर-साइड कॉन्फ़िगरेशन का इस्तेमाल करके, Canary मोड (या इसके लिए ज़िम्मेदार फ़्लैग आईडी) को रिमोटली बंद किया जा सकता है. इससे लाइब्रेरी तुरंत अपने स्टेबल, लेगसी फ़ॉलबैक व्यवहार पर वापस आ जाती है. इसके लिए, ऐप्लिकेशन में इमरजेंसी हॉटफ़िक्स या बाइनरी रिलीज़ की ज़रूरत नहीं होती.

कैनरी मोड और फ़्लैग कॉन्फ़िगर करना

Flags एपीआई, ग्लोबल कैनरी मोड और अलग-अलग फ़्लैग ओवरराइड को कंट्रोल करने के तरीके उपलब्ध कराता है.

ग्लोबल कैनरी मोड

कैनरी मोड में शामिल सभी सुविधाओं को चालू या बंद करने के लिए:

Kotlin

// Enable or disable Canary mode globally (defaults to true).
Flags.setCanaryModeEnabled(false)

Java

// Enable or disable Canary mode globally (defaults to true).
Flags.setCanaryModeEnabled(false);

अलग-अलग फ़्लैग को बदलना

ग्लोबल Canary मोड की सेटिंग के अलावा, कुछ फ़्लैग को अलग से भी चालू या बंद किया जा सकता है:

Kotlin

// Explicitly enable an experimental flag.
Flags.enableFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION)

// Explicitly disable a flag.
Flags.disableFlag(Flags.FLAG_DYNAMIC_SCHEDULING)

Java

// Explicitly enable an experimental flag.
Flags.enableFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION);

// Explicitly disable a flag.
Flags.disableFlag(Flags.FLAG_DYNAMIC_SCHEDULING);

साफ़ तौर पर तय किए गए ओवरराइड को, ग्लोबल कैनरी मोड के डिफ़ॉल्ट के मुकाबले हमेशा प्राथमिकता दी जाती है.

फ़्लैग की स्थिति की जांच करना

यह देखने के लिए कि आपके कोड में Canary मोड या कोई खास फ़्लैग चालू है या नहीं:

Kotlin

// Query whether Canary mode is active globally.
val isCanaryActive = Flags.isCanaryModeEnabled()

// Query whether a specific flag is active.
val isFeatureActive = Flags.isEnabled(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION)

Java

// Query whether Canary mode is active globally.
boolean isCanaryActive = Flags.isCanaryModeEnabled();

// Query whether a specific flag is active.
boolean isFeatureActive = Flags.isEnabled(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION);

फ़्लैग रिज़ॉल्यूशन ऑर्डर

जब Media3 यह जांच करता है कि रनटाइम के दौरान कोई सुविधा चालू है या नहीं, तो वह इस क्रम में स्थिति को हल करता है:

  1. रनटाइम के दौरान साफ़ तौर पर ओवरराइड करना: अगर फ़्लैग आईडी के लिए enableFlag या disableFlag को कॉल किया गया था, तो ओवरराइड की गई वैल्यू दिखती है.
  2. स्टैटिक लाइब्रेरी स्टेट: अगर फ़्लैग को स्टैटिक तौर पर बंद किया गया है (उदाहरण के लिए, डेवलपमेंट के शुरुआती चरण में मौजूद कोई सुविधा, जो Canary मोड के लिए अभी तैयार नहीं है) या स्टैटिक तौर पर चालू किया गया है (Canary मोड से ग्रेजुएट हुई कोई सुविधा, जिसमें कुछ समय के लिए ऑप्ट-आउट करने का फ़ॉलबैक मौजूद है), तो वह स्टैटिक वैल्यू दिखाई जाती है.
  3. कैनरी मोड की स्थिति: इसके अलावा, फ़्लैग ग्लोबल कैनरी मोड की सेटिंग के मुताबिक काम करता है. अगर कैनरी मोड true है, तो यह चालू होता है और अगर false है, तो यह बंद होता है.

शुरुआत करने से जुड़ी ज़रूरी शर्तें

किसी भी Media3 कॉम्पोनेंट (जैसे, ExoPlayer, Transformer या MediaSession) को इंस्टैंशिएट करने से पहले, फ़्लैग कॉन्फ़िगर करें:

  • शुरुआती सेटअप: ऐप्लिकेशन के स्टार्टअप के दौरान (उदाहरण के लिए, Application.onCreate में) या ऐप्लिकेशन की मीडिया लेयर को शुरू करने से पहले, Flags को कॉन्फ़िगर करें.
  • थ्रेड की सुरक्षा: Media3 के कॉम्पोनेंट, इंस्टैंशिएशन के दौरान फ़्लैग पढ़ते हैं और उन वैल्यू को इंटरनल प्लेबैक और प्रोसेसिंग थ्रेड में भेजते हैं. पक्का करें कि Media3 कॉम्पोनेंट बनाने से पहले, फ़्लैग कॉन्फ़िगरेशन हो. प्लेयर या ट्रांसफ़ॉर्मर के चालू होने के दौरान, फ़्लैग में बदलाव नहीं किया जा सकता.

रिमोट कॉन्फ़िगरेशन के साथ इंटिग्रेट करना

हमारा सुझाव है कि आप अपने रिमोट कॉन्फ़िगरेशन प्लैटफ़ॉर्म में तीन पैरामीटर दिखाएं:

  • media3_canary_mode_enabled (बूलियन): Canary मोड के लिए ग्लोबल टॉगल (डिफ़ॉल्ट रूप से true पर सेट होता है).
  • media3_force_enable_flags (List of Integers): Specific flag IDs to force-enable for targeted trials.
  • media3_force_disable_flags (List of Integers): Specific flag IDs to force-disable if an issue is discovered.

प्लेयर इंस्टेंस बनाने से पहले, स्टार्टअप के दौरान ये वैल्यू लागू करें:

Kotlin

fun initializeMedia3Flags(
  canaryModeEnabled: Boolean,
  forceEnabledFlags: List<Int>,
  forceDisabledFlags: List<Int>,
) {
  // 1. Set global Canary mode state.
  Flags.setCanaryModeEnabled(canaryModeEnabled)

  // 2. Apply explicit force-enable overrides.
  for (flagId in forceEnabledFlags) {
    Flags.enableFlag(flagId)
  }

  // 3. Apply explicit force-disable overrides (remote kill switch).
  for (flagId in forceDisabledFlags) {
    Flags.disableFlag(flagId)
  }
}

Java

public static void initializeMedia3Flags(
    boolean canaryModeEnabled,
    List<Integer> forceEnabledFlags,
    List<Integer> forceDisabledFlags) {
  // 1. Set global Canary mode state.
  Flags.setCanaryModeEnabled(canaryModeEnabled);

  // 2. Apply explicit force-enable overrides.
  for (int flagId : forceEnabledFlags) {
    Flags.enableFlag(flagId);
  }

  // 3. Apply explicit force-disable overrides (remote kill switch).
  for (int flagId : forceDisabledFlags) {
    Flags.disableFlag(flagId);
  }
}

फ़्लैग की मदद से जांच करना

फ़ीचर फ़्लैग से प्रभावित कोड पाथ के लिए यूनिट टेस्ट या Robolectric टेस्ट लिखते समय, androidx.media3.test.utils.Media3FlagsRule का इस्तेमाल करें. यह media3-test-utils मॉड्यूल में उपलब्ध है. इससे यह पक्का किया जा सकता है कि टेस्ट, एक-दूसरे की स्टैटिक स्थिति को खराब न करें.

Media3FlagsRule की मदद से, अपने-आप क्लीनअप होने की सुविधा

Media3FlagsRule जोड़ने से यह पक्का होता है कि हर टेस्ट के बाद, फ़्लैग ओवरराइड और Canary मोड में किए गए सभी बदलाव अपने-आप रीसेट हो जाएं:

Kotlin

class MyPlayerTest {

  @get:Rule val flagsRule = Media3FlagsRule(this)

  @Test
  fun playback_withFeatureFlagEnabled() {
    Flags.enableFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION)
    // Run test with the flag enabled...
  }
}

Java

public static class MyPlayerTest {

  @Rule public final Media3FlagsRule flagsRule = new Media3FlagsRule(this);

  @Test
  public void playback_withFeatureFlagEnabled() {
    Flags.enableFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION);
    // Run test with the flag enabled...
  }
}

पैरामीटर वाली टेस्टिंग

फ़्लैग की स्थितियों के हिसाब से पैरामीटर वाले टेस्ट चलाने के लिए, Media3FlagsRule को @BindFlag और @BindCanaryMode एनोटेशन के साथ जोड़ा जा सकता है:

Kotlin

class MyParameterizedPlayerTest {

  @BindCanaryMode var canaryMode: Boolean = false

  @BindFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION) var perStreamProgression: Boolean = false

  @get:Rule val flagsRule = Media3FlagsRule(this)

  @Test
  fun playback() {
    // Flags are automatically set for each test parameter combination.
  }
}

Java

public static class MyParameterizedPlayerTest {

  @BindCanaryMode public boolean canaryMode;

  @BindFlag(Flags.FLAG_PER_STREAM_MEDIA_PROGRESSION)
  public boolean perStreamProgression;

  @Rule public final Media3FlagsRule flagsRule = new Media3FlagsRule(this);

  @Test
  public void playback() {
    // Flags are automatically set for each test parameter combination.
  }
}

डाइग्नोस्टिक्स और लॉगिंग

Media3 में, गड़बड़ी का पता लगाने वाले टूल मौजूद हैं. इनकी मदद से, प्लेबैक शुरू होने और रनटाइम के दौरान, चालू फ़्लैग और Canary मोड की स्थितियों की पुष्टि की जा सकती है.

शुरुआत करने के लॉग

जब ExoPlayer इंस्टेंस को शुरू किया जाता है, तो यह लाइब्रेरी के वर्शन के साथ-साथ, चालू कैनरी की स्थिति और साफ़ तौर पर किए गए किसी भी बदलाव को logcat में प्रिंट करता है:

ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.10.1] [flame, Pixel 4, Google, 33] [Canary:ON]

अगर ओवरराइड चालू हैं, तो सिर्फ़ डिफ़ॉल्ट स्थिति से अलग होने वाले बदलावों को ही सूची में शामिल किया जाता है:

ExoPlayerImpl: Init 59a18ab [AndroidXMedia3/1.10.1] [flame, Pixel 4, Google, 33] [Canary:ON, Overrides: enabled=[1], disabled=[3]]

प्रोग्रामैटिक जांच

प्रोग्राम के हिसाब से, फ़ॉर्मैट की गई डाइग्नोस्टिक्स स्ट्रिंग या क्वेरी ओवरराइड सूचियां वापस पाई जा सकती हैं. उदाहरण के लिए, अपने ऐप्लिकेशन की क्रैश रिपोर्ट या आंकड़ों में फ़्लैग की स्थिति शामिल करने के लिए:

Kotlin

// Get formatted string representing active Canary state and overrides.
val flagLogString = Flags.getLogString()

// Query explicit override IDs if needed.
val enabledFlags = Flags.getEnabledOverrides()
val disabledFlags = Flags.getDisabledOverrides()

Java

// Get formatted string representing active Canary state and overrides.
String flagLogString = Flags.getLogString();

// Query explicit override IDs if needed.
int[] enabledFlags = Flags.getEnabledOverrides();
int[] disabledFlags = Flags.getDisabledOverrides();

फ़्लैग लाइफ़साइकल

Media3 में फ़्लैग, अस्थायी तौर पर इस्तेमाल करने के लिए डिज़ाइन किए गए हैं:

  1. डेवलपमेंट: Flags.java में फ़्लैग आईडी के पीछे, नया ऑप्टिमाइज़ेशन या सुविधा जोड़ी जाती है.
  2. कैनरी मोड: पुष्टि होने और सामान्य इस्तेमाल के लिए तैयार होने के बाद, यह सुविधा सभी रिलीज़ में कैनरी मोड के तहत चालू हो जाती है.
  3. प्रमोशन और क्लीनअप: प्रोडक्शन में स्थिरता साबित करने के लिए, कुछ समय तक इंतज़ार करने के बाद, सुविधा को लाइब्रेरी में हमेशा के लिए चालू कर दिया जाता है. साथ ही, फ़्लैग कॉन्स्टेंट, फ़ॉलबैक कोड पाथ, और शर्तों के हिसाब से की जाने वाली जांचों को हटा दिया जाता है.

अगर आपको किसी फ़ीचर फ़्लैग से जुड़ी कोई समस्या आती है, तो कृपया AndroidX Media3 GitHub के समस्या ट्रैकर पर इसकी शिकायत करें. इससे टीम, फ़ीचर फ़्लैग को स्थायी तौर पर प्रमोट करने से पहले समस्या को हल कर पाएगी.