ارکستراتور را پیکربندی کنید، ارکستراتور را پیکربندی کنید

ارکستراتور یک عامل SDV محلی است که روی هر ماشین مجازی (VM) اجرا می‌شود و مکانیزمی را برای کنترل زمان ایجاد، شروع، توقف یا از بین رفتن بسته‌های سرویس فراهم می‌کند. این کار از طریق پیکربندی ارکستراسیون انجام می‌شود که در آن مجموعه‌ای از قوانین را تعریف می‌کنید که تعیین می‌کنند چه زمانی و چگونه اقدامات روی نمونه‌های بسته سرویس انجام شوند. این قوانین بر اساس وسیله نقلیه، برق و حالت‌های سفارشی هستند.

شما می‌توانید Orchestrator را در پیکربندی APEXها یا از طریق پیکربندی‌های هر ماشین مجازی پیکربندی کنید. این سیستم پیکربندی توزیع‌شده به بخش‌هایی از هر بسته سرویس اجازه می‌دهد تا به‌طور مستقل از طریق رجیستری بسته سرویس، همانطور که در اینجا نشان داده شده است، به‌روزرسانی شوند.

نمودار پیکربندی توزیع‌شده‌ی هماهنگ‌کننده

شکل ۱. نمودار پیکربندی هماهنگ‌کننده.

پیکربندی‌های مستقل از خودرو بسته به سازنده اصلی (OEM) یا خودرو تغییر نمی‌کنند. این پیکربندی در تمام خودروهای هر سازنده اصلی (OEM) یکسان باقی می‌ماند. پیکربندی‌های خاص خودرو می‌توانند در خودروهای مختلف توسط سازندگان اصلی (OEM) متفاوت باشند، اگرچه پیکربندی می‌تواند برای تمام خودروهای ساخته شده توسط یک سازنده اصلی (OEM) خاص یکسان باشد.

پیکربندی APEXها

در زمان اجرا، Orchestrator به رجیستری بسته‌های سرویس می‌رود تا یک SDV Orchestration برای هر بسته سرویس دریافت کند، هر پیکربندی را بارگذاری و تجزیه کند. برای کسب اطلاعات بیشتر، به متادیتای Orchestration مراجعه کنید.

پیکربندی به ازای هر ماشین مجازی

وقتی Orchestrator شروع به کار می‌کند، پیکربندی ماشین مجازی (در صورت وجود) را بارگذاری و تجزیه می‌کند. مسیر مطلق این فایل پیکربندی از طریق ویژگی‌های سیستمی persist.sdv.orchestrator_config_path و ro.boot.sdv.orchestrator_config_path مشخص می‌شود.

سیستم مسیر فایل پیکربندی ماشین مجازی را در هنگام بوت بر اساس سلسله مراتب زیر تعیین می‌کند:

  1. سیستم ویژگی persist.sdv.orchestrator_config_path را بررسی می‌کند. اگر مقداری داشته باشد، از آن مسیر استفاده می‌شود. این مقدار در طول راه‌اندازی مجدد سیستم حفظ می‌شود یا در زمان اجرا تنظیم می‌شود.

  2. اگر persist.sdv.orchestrator_config_path خالی باشد، سیستم سپس ویژگی ro.boot.sdv.orchestrator_config_path را بررسی می‌کند. اگر ویژگی ro.boot.sdv مقداری داشته باشد، آن مسیر در ویژگی persist کپی می‌شود و برای بوت فعلی و تمام بوت‌های آینده (مگر اینکه لغو شود) استفاده می‌شود.

persist.sdv.orchestrator_config_path

persist.sdv.orchestrator_config_path ویژگی اصلی مورد استفاده توسط عامل SDV Orchestrator برای دریافت مسیر فایل پیکربندی آن است. این یک ویژگی پایدار است، به این معنی که مقدار آن در طول راه‌اندازی مجدد دستگاه ذخیره می‌شود. می‌توانید مقدار را در زمان اجرا تغییر دهید، که برای آزمایش یا سناریوهای خاص (به عنوان مثال، آزمایش‌های سرتاسری) مفید است.

شما می‌توانید مقدار را در زمان اجرا با استفاده از دستور setprop و در زمان ساخت با استفاده از یک makefile (با پسوند .mk ) یا یک فایل اسکریپت منبع، با پسوند .rc تنظیم کنید.

تنظیم ویژگی در زمان اجرا

تنظیم ویژگی در زمان اجرا برای آزمایش یا ایجاد تغییرات موقت مفید است، زیرا مقدار در طول راه‌اندازی مجدد سیستم ذخیره می‌شود:

adb root
adb shell setprop persist.sdv.orchestrator_config_path {$path_to_file}.textproto

تنظیم ویژگی در زمان ساخت

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

# Add this line to a product's or device's .mk file
PRODUCT_PROPERTY_OVERRIDES += persist.sdv.orchestrator_config_path={$path_to_file}.textproto

همچنین می‌توانید این ویژگی را درون یک فایل اسکریپت منبع تنظیم کنید:

# Add this line to an .rc file
on {$property}
    setprop persist.sdv.orchestrator_config_path {$path_to_file}.textproto

مسیر پیکربندی ro.boot.sdv.orchestrator_config

ro.boot.sdv.orchestrator_config_path یک ویژگی فقط خواندنی زمان بوت است که برای ارائه مقدار اولیه برای ویژگی persist.sdv.orchestrator_config_path استفاده می‌شود. اگر persist.sdv.orchestrator_config_path هنگام بوت شدن سیستم خالی باشد، مقدار ro.boot.sdv.orchestrator_config_path در آن کپی می‌شود. پس از تنظیم persist.sdv.orchestrator_config_path ، در بوت‌های بعدی توسط این ویژگی بازنویسی نمی‌شود.

شما می‌توانید ro.boot.sdv.orchestrator_config_path با استفاده از bootconfig یا cmdline کرنل تنظیم کنید.

فرمت فایل

پیکربندی ارکستراسیون را در قالب .textproto (مثلاً به صورت متن ساختاریافته) تعریف کنید تا پیکربندی‌های جدید بتوانند در زمان اجرا بارگیری شوند.

نحو پیکربندی

این بخش سینتکس پیکربندی را شرح می‌دهد.

بسته‌های خدماتی

هر بسته سرویس باید با پیکربندی بسته سرویس تعریف شود، که بسته را در Orchestrator شناسایی می‌کند و برای مدیریت چرخه حیات نمونه بسته استفاده می‌شود. پیکربندی بسته سرویس موارد زیر را تعریف می‌کند:

  • InstanceToGroupMapping به شما امکان می‌دهد نمونه‌ای از بسته سرویس را در یک گروه قرار دهید تا وابستگی‌هایی بین نمونه‌های یک بسته سرویس مشابه ایجاد شود.

  • InstancesStates حالت‌های مختلف را برای نمونه بسته سرویس تعریف می‌کند.

  • InstancesStateConfiguration وضعیتی (از InstancesStates ) را تعریف می‌کند که اگر شرط به true ارزیابی شود، یک نمونه بسته سرویس باید روی آن تنظیم شود.

  • ServiceBundleConfig حاوی اطلاعاتی در مورد بسته سرویس خاص و نمونه‌های آن است. این بسته شامل InstanceToGroupMapping و InstancesStateConfiguration مربوط به آن بسته است.

  • CustomModes فهرستی از حالت‌های سفارشی را تعریف می‌کند که بسته نرم‌افزاری مجاز به انتشار آنهاست. CustomModes برای جلوگیری از تغییر مقدار یک حالت سفارشی توسط یک بسته نرم‌افزاری غیرمجاز استفاده می‌شود. این فیلد اختیاری است، زیرا بسته نرم‌افزاری سرویس ممکن است در هیچ حالت سفارشی منتشر نشود. برای کسب اطلاعات بیشتر، به حالت‌های سفارشی مراجعه کنید.

پیکربندی بسته نرم افزاری مورد نیاز

حداقل، پیکربندی بسته نرم‌افزاری این ویژگی‌ها را ارائه می‌دهد:

service_bundle_config {
    package_name: "package_name"
    service_bundle_name: "service_bundle_name"

    instance: "instance_1"
    instance: "instance_n"
}

این اعلان، n نمونه بسته سرویس را با FQIN های مربوطه تعریف می‌کند:

vm_name.package_name.service_bundle_name.instance_1

vm_name.package_name.service_bundle_name.instance_n

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

پیکربندی نمونه‌ها

اعلام نمونه‌های بسته سرویس هیچ تاثیری ندارد. برای اجرا توسط Orchestrator، نمونه‌ها باید پیکربندی شوند. به عنوان مثال، Orchestrator باید از شرایط (یا وضعیت ماشین مجازی یا وسیله نقلیه) که یک نمونه باید اجرا شود، مطلع شود. برای پیکربندی نمونه‌ها، وضعیت‌های پیکربندی باید از طریق موارد زیر تعریف شوند:

  • condition ، عبارتی روی ماشین مجازی یا وضعیت خودرو است که باید ارزیابی شود.

  • instances_states مجموعه‌ای از حالت‌ها به ازای هر نمونه است که در صورت true شرط، باید اعمال شوند.

برای کسب اطلاعات بیشتر، به بخش شرایط مراجعه کنید.

service_bundle_config {
    package_name: "oem.package"
    service_bundle_name: "OemApplication"

    instance: "adaptive_light"
    instance: "reserve_light"

    state {
        condition {
            power_state: "ON"
        }

        instances_states {
            started: "adaptive_light"
            created: "reserve_light"
        }
    }
}

نگاشت نمونه به گروه

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

service_bundle_config {
    package_name: "oem.package"
    service_bundle_name: "OemApplication"

    instance: "fog_front_light"
    instance: "fog_rear_light"
    instance: "turn_signal_light"
    instance: "light_flasher_display"

    # Declare that fog_light contains fog_front_light and fog_rear_light.
    group_mapping {
        group: "fog_light"
        instance: "fog_front_light"
        instance: "fog_rear_light"
    }

    # Declare that flasher_light contains turn_signal_light and light_flasher_display.
    group_mapping {
        group: "flasher_light"
        instance: "turn_signal_light"
        instance: "light_flasher_display"
    }
}

طرحواره اولیه

در اینجا یک نمونه طرح اولیه آورده شده است:

// Service bundle configuration.
//
// Defines service bundle data, its instances and configuration for instances
// states depending on the state of the system
message ServiceBundleConfig {
  // Required. Name of the service bundle.
  string service_bundle_name = 1;

  // Required. Package name of the service bundle.
  string package_name = 2;

  // Required. Service instances.
  repeated string instance = 3;

  // Configuration for instances states depending on the state of the system.
  repeated InstancesStateConfiguration state = 4;

  // Mapping of groups to their member service instances.
  repeated InstanceToGroupMapping group_mapping = 5;

  // Custom modes that this service bundle is allowed to set.
  repeated string custom_mode = 6;

  // Defines the retry policies for specific instances.
  // If multiple mappings target the same instance, the one with the highest `max_retries`
  // value takes precedence. This applies across all configuration files.
  repeated InstanceToRetryMapping retry_mapping = 7;
}

// Mapping of instances to their retry configuration.
message InstanceToRetryMapping {
  // Required.
  //
  // Name of the instances for which the given retry configuration is applied.
  repeated string instance = 1;

  // Required.
  //
  // The configuration that defines the restart and retry strategy for the instances.
  RetryConfiguration retry_config = 2;

  // Configuration for retry and restart.
  // This configuration is applied after a failure on a transition or after the bundle instance
  // has crashed. Upon a successful operation, the retry counter are reset to max_retries. This
  // configuration can be applied to any service bundle, not only the monitored ones. If the
  // configuration is not provided or none of the optional fields are filled, the default behavior
  // stated is applied (the value from `ro.boot.sdv.orchestrator.recovery.max_retries`
  // or zero if not set).
  message RetryConfiguration {
    // The number of times a retry/restart operation can be performed.
    // Defines the number of times the Orchestrator retries a transition
    // after a transient failure or after a bundle crash notification.
    // This applies to creating, starting and destroying operations.
    // The retry count resets to max_retries after a successful operation.
    // If not set, the default configured value in the
    // `ro.boot.sdv.orchestrator.recovery.max_retries` is used, or-if not set-
    // it fallbacks to zero.
    optional uint32 max_retries = 1;
  }
}

// Mapping of groups to their member service instances.
message InstanceToGroupMapping {
  // Required. Names of groups to which members are added.
  //
  // Group behavior is defined in VM configuration.
  repeated string group = 1;

  // Required. Names of instances to be included in the groups.
  //
  // Can reference only instance defined in the same config file.
  repeated string instance = 2;
}

// Describes the state the service instances should be in after the state is executed.
//
// If there is no valid configuration for the instance in the specific system state, such instance is transitioned to the "destroyed" state.
//
// For the GroupsStates definition to be useful, at least one item should be present in any of the fields.
message InstancesStates {
  // Names of the instances that must be in a "created" state.
  repeated string created = 1;

  // Names of the instances that must be in a "started" state, overrides "created" state.
  repeated string started = 2;

  // Names of the instances that must not run, overrides all other states.
  repeated string destroyed = 3;
}

// Configuration for instances states depending on the state of the system.
message InstancesStateConfiguration {
  // Condition for the system state under which the related instances states should be executed by Orchestrator.
  //
  // If omitted, the related instances states are always executed.
  Condition condition = 1;

  // Required. States of service bundle instances to be executed by Orchestrator if the condition is true.
  InstancesStates instances_states = 2;
}

پیکربندی سطح ماشین مجازی

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

ارکستراتور ترتیب اجرای تغییر وضعیت را تضمین نمی‌کند. ارکستراتور هر نمونه را به وضعیت داده شده ارتقا می‌دهد.

گروه‌ها به طور ضمنی با استفاده از نام group در هر یک از بخش‌های پیکربندی تعریف می‌شوند. برای مثال، نگاشت نمونه به گروه، نگاشت گروه به گروه و وضعیت پیکربندی گروه.

نگاشت گروه به گروه

گروه‌ها می‌توانند شامل گروه‌های دیگری باشند. با اعلام اینکه group_1 شامل subgroup_2 است، ما عملاً تمام نمونه‌های سرویس را از subgroup_2 به group_1 اضافه می‌کنیم.

برای مثال:

# Declare that body contains fog_light and flasher_light.
group_mapping {
    group: "body"
    subgroup: "fog_light"
    subgroup: "flasher_light"
}

پیکربندی یک گروه

اعلام یک گروه هیچ تاثیری ندارد. برای اینکه گروه‌ها توسط Orchestrator اجرا شوند، باید پیکربندی شوند. به عنوان مثال، Orchestrator باید مطلع شود که گروه‌ها تحت چه شرایط یا وضعیتی از ماشین مجازی یا وسیله نقلیه باید اجرا شوند.

شما می‌توانید گروه‌ها را به روشی مشابه نمونه‌های سرویس پیکربندی کنید، یعنی با استفاده از حالت‌های پیکربندی. تنها تفاوت، استفاده از groups_states به جای instances_states در سینتکس است:

state {
    condition {
        power_state: "ON"
    }

    groups_states {
        started: "Body"
        started: "Adas"
    }
}

طرحواره اولیه

در اینجا یک نمونه طرح اولیه آورده شده است:

// VM configuration.
//
// Defines group-to-group mappings and configuration for groups
// states depending on the state of the system.
//
// Configurations of service bundles can also be defined in VM configuration (as well as in a separate configuration file).
message VmConfig {
  // Group to member groups mapping.
  repeated GroupToGroupMapping group_mapping = 1;

  // Configuration of group states.
  repeated GroupsStateConfiguration state = 2;

  // Required. We also allow to configure individual service bundles in the VM config, to simplify development and migration from the monolithic configuration.
  repeated ServiceBundleConfig service_bundle_config = 3;
}

// Mapping of groups to their member groups.
message GroupToGroupMapping {
  // Required. Names of groups to which members are added.
  repeated string group = 1;

  // Required. Names of member groups to be included in the groups.
  repeated string subgroup = 2;
}

// Describes the state the service instance groups should be in after the state is executed.
//
// If group configuration is valid in a specific system state, the configured state is applied to
// all group members. After that, the normal service instance configuration rules still apply:
// - "destroyed" > "started" > "created" precedence
// - not configured means the instance should be moved to the default state
//
// For the GroupsStates definition to be useful, at least one item should be present in any of the fields.
message GroupsStates {
  // Names of the groups that must be in a "created" state.
  repeated string created = 1;

  // Names of the groups that must be in a "started" state, overrides "created" state.
  repeated string started = 2;

  // Names of the groups that must not run, overrides all other states.
  repeated string destroyed = 3;
}

// Configuration for group states depending on the state of the system.
message GroupsStateConfiguration {
  // Condition for the system state under which the related group states should be executed by  Orchestrator.
  //
  // If omitted, the related groups states are always executed.
  Condition condition = 1;

  // Required. States of service bundle groups to be executed by Orchestrator if the condition  is true.
  GroupsStates groups_states = 2;
}

حالت‌های پیکربندی

وضعیت‌های پیکربندی (states) زمان شروع، توقف یا از بین رفتن یک نمونه یا گروه سرویس را تعریف می‌کنند و شامل conditions و instances_states ) (پیکربندی بسته) و وضعیت‌های گروه ( groups_states ) (پیکربندی ماشین مجازی) می‌شوند.

شرایط

شرط‌ها به مدل اجازه می‌دهند یک شرط بولی داشته باشد که تحت آن، وقتی مقدار آن true ، حالت نمونه تعریف‌شده اعمال می‌شود. یک شرط دارای این ویژگی‌ها است:

  • عبارت بولی دلخواه پیچیده (که با عبارات and یا not تشکیل شده است) بر اساس سیگنال‌های پشتیبانی شده مانند قدرت، وسیله نقلیه و حالت سفارشی.

  • (اختیاری) وضعیت پیکربندی بدون شرط همیشه فعال است، به این معنی که مقدار آن true است.

حالت‌های نمونه و حالت‌های گروه

instances_states و groups_states این ویژگی‌ها را دارند.

  • با توجه به active حالت، تعیین کنید که عامل هماهنگ‌سازی برای اعمال روی نمونه‌ها یا گروه‌های داده شده به کدام حالت‌ها نیاز دارد.

  • هنگام اعمال یک وضعیت به گروه، آن وضعیت به هر نمونه از بسته سرویس در گروه اعمال می‌شود. هیچ ترتیبی برای زمان ورود نمونه‌ها به وضعیت اعمال نمی‌شود.

ایالت‌های پشتیبانی‌شده عبارتند از:

  • پس از فراخوانی Service::on_start started می‌شود.

  • created

    • بعد از اینکه Service::new فراخوانی شود، اما قبل از اینکه Service::on_start فراخوانی شود.

      یا

    • بعد از اینکه Service::on_stop فراخوانی می‌شود، اما قبل از اینکه Service::drop فراخوانی شود.

  • پس از destroyed Service::drop از بین می‌رود.

مجموعه قوانین

وضعیت پیکربندی می‌تواند بسته به شرایط، فعال یا غیرفعال باشد. چندین وضعیت می‌توانند در هر زمانی فعال باشند. هنگامی که یک عامل هماهنگ‌کننده، به‌روزرسانی سیگنال را دریافت می‌کند، تمام وضعیت‌های پیکربندی قبل از اصلاح چرخه عمر بسته‌های سرویس ارزیابی می‌شوند. وضعیت‌های نمونه سرویس طبق این قوانین ارزیابی می‌شوند:

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

  • وقتی یک یا چند حالت فعال اعمال می‌شود، این اولویت اعمال می‌شود:

    1. destroyed اولویت مطلق دارد.
    2. started بر created اولویت دارد.

طرحواره اولیه

در اینجا یک نمونه طرح اولیه آورده شده است:

// A root boolean condition.
message Condition {
  // Required.
  oneof root {
    // VPM power state condition.
    string power_state = 1;
    // VPM vehicle state condition.
    string vehicle_state = 2;
    // Custom mode state condition.
    CustomState custom_state = 3;
    // Negation of a nested condition.
    Condition not = 4;
    // Logical 'and' between conditions grouped in expression.
    Expression and = 5;
    // Logical 'or' between conditions grouped in expression.
    Expression or = 6;
  }
}

// Representation of Custom state condition.
//
// Custom mode(s) are defined by the OEM and are not standardized by the platform, in contrast with
// VPM modes (i.e. power and vehicle mode).
message CustomState {
  // Custom mode being checked.
  string mode = 1;
  // State of the custom mode.
  string state = 2;
}

// A set of conditions united under an 'and' or 'or' expression.
//
// Evaluation type ('and' or 'or') depends on the field in [Condition]/[Expression], where the
// expression is being used.
//
// At least one value in at least one of the fields is required.
message Expression {
  // VPM power state condition.
  repeated string power_state = 1;
  // VPM vehicle state condition.
  repeated string vehicle_state = 2;
  // Custom mode state condition.
  repeated CustomState custom_state = 3;
  // Negation of a nested condition.
  repeated Condition not = 4;
  // Logical 'and' between conditions grouped in expression.
  repeated Expression and = 5;
  // Logical 'or' between conditions grouped in expression.
  repeated Expression or = 6;
}

استراتژی بازیابی از خرابی و راه‌اندازی مجدد

Orchestrator مکانیزمی قوی برای مدیریت خرابی‌های بسته سرویس و شکست‌های انتقال چرخه عمر ارائه می‌دهد. از آنجا که Orchestrator دیدی جامع از وضعیت‌های سرویس دارد و انتقال‌های حالت را مدیریت می‌کند، مناسب‌ترین مؤلفه برای اجرای استراتژی راه‌اندازی مجدد و تلاش مجدد است. مدیر چرخه حیات (LM) خرابی‌های بسته سرویس را از طریق اعلان‌های مرگ binder به Orchestrator گزارش می‌دهد. برای جلوگیری از فراخوانی‌های غیرضروری binder به LM، Orchestrator آخرین وضعیت هر بسته (چه موفق و چه ناموفق) را ذخیره می‌کند و اگر آخرین وضعیت شناخته شده با وضعیت درخواستی جدید یکسان باشد، انتقال‌ها را دوباره اعمال نمی‌کند.

پیکربندی را دوباره امتحان کنید

شما می‌توانید استراتژی راه‌اندازی مجدد و تلاش مجدد را برای هر نمونه در پیکربندی Orchestrator خود با استفاده از retry_mapping تعریف کنید. اگر max_retries در پیکربندی تنظیم نشده باشد، مقدار پیش‌فرض از ویژگی سیستم ro.boot.sdv.orchestrator.recovery.max_retries گرفته می‌شود. اگر این ویژگی تنظیم نشده باشد، مقدار به 0 تغییر می‌کند.

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

نمونه پیکربندی

service_bundle_config {
  package_name: "oem.package"
  service_bundle_name: "OemApplication"
  instance: "fog_front_light"
  instance: "fog_rear_light"

  # Defines the restart configuration mapping for specific instances.
  retry_mapping {
    instance: "fog_front_light"
    instance: "fog_rear_light"
    retry_config {
      max_retries: 3
    }
  }
}

رفتار بهبودی

منطق راه‌اندازی مجدد و تلاش مجدد Orchestrator به طرز ماهرانه‌ای چندین سناریوی شکست را مدیریت می‌کند:

  • خرابی عملکرد عادی : اگر یک بسته سرویس هنگام اجرا دچار خرابی شود، Orchestrator استراتژی راه‌اندازی مجدد را اعمال می‌کند و تلاش می‌کند تا بسته را بر اساس تلاش‌های مجدد باقی مانده به آخرین حالت درخواستی خود بازگرداند.
  • خرابی در حین انتقال حالت : اگر یک بسته نرم‌افزاری هنگام اعمال حالت جدید دچار خرابی شود، درخواست راه‌اندازی مجدد در صف انتظار قرار گرفته و بعداً پردازش می‌شود. پس از پردازش درخواست، Orchestrator بررسی می‌کند که آخرین وضعیت برای نمونه کدام بوده است و فقط در صورتی که نمونه در آخرین وضعیت درخواستی (از آخرین انتقال حالت) نباشد، راه‌اندازی مجدد را اعمال می‌کند.
  • حالت جدید در حین بازیابی : اگر Orchestrator درخواستی برای انتقال به حالت جدید در حین راه‌اندازی مجدد یک بسته نرم‌افزاری (یا در صف نمونه‌هایی برای راه‌اندازی مجدد) دریافت کند، بازیابی در حال انجام را لغو می‌کند. انتقال به حالت جدید آغاز می‌شود و شمارنده تلاش مجدد بازنشانی می‌شود تا امکان مجموعه‌ای جدید از تلاش‌ها برای حالت هدف جدید فراهم شود.

هماهنگ‌کننده (Orchestrator) بین انواع مختلف خطا که توسط مدیر چرخه حیات (Lifecycle Manager) برگردانده می‌شود، تمایز قائل می‌شود تا استراتژی تلاش مجدد را تعیین کند:

  • خطاهای گذرا ( SERVICE_NOT_FOUND ، OPERATION_FAILED ، INTERNAL_ERROR ): ارکستراتور بدون انجام هیچ اقدام پاکسازی خاصی، عملیات را دوباره امتحان می‌کند.
  • خطاهای مداوم ( VALUE_CORRUPTED ، INVALID_ARGUMENT ): ارکستراتور فرض می‌کند که بسته سرویس ممکن است در وضعیت خراب باشد و قبل از تلاش مجدد برای اطمینان از راه‌اندازی مجدد کامل، سعی می‌کند نمونه سرویس را از بین ببرد.
  • خطاهای دائمی ( PERMISSION_DENIED ): عملیات دوباره انجام نمی‌شود و بسته در حالت غیرقابل بازیابی در نظر گرفته می‌شود.

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

برای جلوگیری از حلقه‌های بازیابی بی‌نهایت برای بسته‌هایی که مرتباً خراب می‌شوند یا از کار می‌افتند، شمارنده‌ی تلاش مجدد فقط پس از موفقیت یک عملیات چرخه‌ی عمر یا زمانی که انتقال به حالت جدید درخواست می‌شود، به max_retries بازنشانی می‌شود. اگر یک بسته به دلیل خرابی‌های متوالی (به عنوان مثال، خرابی انتقال و به دنبال آن خرابی) تلاش‌های مجدد خود را تمام کند، تا زمانی که شمارنده‌ی تلاش مجدد بازنشانی نشود، مجدداً راه‌اندازی نمی‌شود.

گزارش ایالت به ناظر سلامت

ارکستراتور یک رابط اتصال داخلی را در معرض نمایش قرار می‌دهد که مانیتور سلامت (HM) آن را ثبت می‌کند و به آن امکان می‌دهد به‌روزرسانی‌های مداوم در مورد وضعیت همه بسته‌های سرویس را دریافت کند. از طریق این رابط، ارکستراتور به طور فعال هر دو مورد زیر را گزارش می‌دهد:

  • وضعیت چرخه حیات: وضعیت مورد نظر نمونه بر اساس پیکربندی فعلی و حالت‌های فعال (مانند شروع شده، ایجاد شده یا از بین رفته).
  • وضعیت بازیابی: وضعیت رسیدن به وضعیت چرخه عمر مورد نظر، که نشان می‌دهد آیا نمونه عملیاتی است، در حال حاضر پس از یک شکست در حال تلاش مجدد است، یا پس از اتمام تمام تلاش‌های مجدد، در بازیابی ناموفق بوده است.

این اطلاعات برای همه موارد، از جمله مواردی که برای نظارت بر ضربان قلب ثبت نشده‌اند، گزارش می‌شود. HM از این اطلاعات برای پیاده‌سازی APIهای خود جهت گزارش وضعیت ماشین مجازی استفاده می‌کند. می‌توانید اطلاعات بیشتر را در بخش نظارت بر سلامت (Health monitoring) بیابید.

مثال‌ها

این بخش مثال‌هایی برای پیکربندی حالت‌ها با شرط‌ها ارائه می‌دهد.

نمونه خدمات پایه
  • هیچ شرطی ندارد و بنابراین همیشه فعال است.
  • یک نمونه سرویس واحد را شروع می‌کند.
state {
  # Note: This state has no condition, hence its actions are valid throughout the lifetime of the program
  instances_states { started: "ServiceBundleName" }
}
نمونه برنامه HVAC
  • وضعیت: فعال زمانی که custom_state != occupancy.OCCUPANCY_EMPTY || custom_state == preheat.PREHEAT_ON .

  • چندین نمونه سرویس مرتبط با HVAC را به محض started اعلام می‌کند.

state {
  condition {
    or {
      # I.e. when the vehicle is occupied (for example, by _DRIVER / _NON_DRIVER / _PET)
      not {
        custom_state {
          mode: "occupancy"
          state: "OCCUPANCY_EMPTY"
        }
      }
      custom_state {
        mode: "preheat"
        state: "PREHEAT_ON"
      }
    }
  }

  # HVAC-related services
  instances_states {
    started: "HvacTemperatureCommand"
    started: "TempSensorDriverZone"
    started: "TempSensorPassengerZone"
    started: "RefrigerantLoop"
  }
}
نمونه صرفه‌جویی در مصرف برق
  • وضعیت: فعال زمانی که custom_state == system_power.SYSTEM_POWER_LOW && custom_state == range_ext.RANGE_EXT_ON .

    این حالت را می‌توان به عنوان حالت صرفه‌جویی در مصرف برق در نظر گرفت.

  • یک نمونه سرویس مرتبط با HVAC را به عنوان destroyed اعلام می‌کند.

  • در این مثال، وقتی حالت‌های SYSTEM_POWER_LOW و RANGE_EXT_ON فعال هستند، برنامه HVAC بدون نمونه سرویس RefrigerantLoop اجرا می‌شود:

    state {
      condition {
        and {
          custom_state {
            mode: "system_power"
            state: "SYSTEM_POWER_LOW"
          }
          custom_state {
            mode: "range_ext"
            state: "RANGE_EXT_ON"
          }
        }
      }
    
      # Disable services with high power consumption
      instances_states { destroyed: "RefrigerantLoop" }
    }
    
نمونه زنده روی عرشه
  • وضعیت: اگر power_state == ON && vehicle_state == LIFE_ON_BOARD فعال می‌شود.

    این حالت را می‌توان به این صورت در نظر گرفت که شخصی در ماشین است و ماشین روشن است .

  • سنسورهای دما را در حال اجرا اعلام می‌کند.

  • وقتی کسی در ماشین است، مواردی مانند دما به دلایل ایمنی کنترل می‌شوند.

state {
  condition {
    and {
      power_state: "ON"
      vehicle_state: "LIFE_ON_BOARD"
    }
  }

  # Temperature monitoring services
  instances_states {
    started: "TempSensorDriverZone"
    started: "TempSensorPassengerZone"
  }
}

مثال‌ها

این بخش مثال‌های کاملی را ارائه می‌دهد که شامل موارد زیر است:

  • یک پیکربندی اولیه در سطح بسته سرویس که یک بسته سرویس با دو نمونه را معرفی می‌کند که هر کدام بخشی از یک گروه هستند.

  • پیکربندی اولیه در سطح ماشین مجازی که منطقی را برای تعامل با گروه‌ها بر اساس حالت‌ها معرفی می‌کند

پیکربندی سطح بسته خدمات

# proto-file: //system/software_defined_vehicle/orchestration/distributed_config/src/protos/service_bundle_config.proto
# proto-message: ServiceBundleConfig

package_name: "oem.package"
service_bundle_name: "OemApplication"
instance: "fog_front_light"
instance: "fog_rear_light"
instance: "turn_signal_light"
custom_mode: "FOG"
custom_mode: "TURN"

group_mapping {
    group: "fog_light"
    instance: "fog_front_light"
    instance: "fog_rear_light"
}

group_mapping {
    group: "flasher_light"
    instance: "turn_signal_light"
}

state {
    condition {
        power_state: "ON"
    }

    instances_states {
        created: "turn_signal_light"
        destroyed: "fog_front_light"
        destroyed: "fog_rear_light"
    }
}

پیکربندی سطح ماشین مجازی

# proto-file: //system/software_defined_vehicle/orchestration/distributed_config/src/protos/vm_config.proto
# proto-message: VmConfig

group_mapping {
    group: "lights"
    subgroup: "fog_light"
    subgroup: "flasher_light"
}

state {
    condition {
        custom_state {
            mode: "FOG"
            state: "ON"
        }
    }
    groups_states {
        started: "fog_light"
    }
}

state {
    condition {
        custom_state {
            mode: "TURN"
            state: "RIGHT"
        }
    }
    groups_states {
        started: "flasher_light"
    }
}

state {
    condition {
        vehicle_state: "SUSPEND_TO_RAM_ENTER"
    }
    groups_states {
        created: "lights"
    }
}

پیکربندی موازی‌سازی مدیریت بسته‌های نرم‌افزاری

ویژگی سیستمی ro.boot.sdv.max_bundles_management_threads یک پارامتر تنظیم کلیدی برای کنترل عملکرد و مصرف منابع در طول عملیات چرخه عمر بسته‌های سرویس است. این ویژگی حداکثر سطح موازی‌سازی را برای تراکنش‌های بسته‌های سرویس تعریف می‌کند و مستقیماً بر دو سرویس اصلی تأثیر می‌گذارد:

  1. موتور ارکستراسیون: این سرویس، ویژگی را می‌خواند تا مشخص کند که ارکستراتور چند فراخوانی همزمان (مثلاً startService ، stopService ) می‌تواند به مدیر چرخه حیات انجام دهد. این امر برای عملکرد در هنگام بوت شدن و انتقال حالت‌ها که در آن بسیاری از بسته‌ها ممکن است به طور همزمان حالت خود را تغییر دهند، بسیار مهم است.

  2. مدیر چرخه حیات: این سرویس از مقدار ویژگی برای محاسبه اندازه مخزن نخ‌های Binder خود استفاده می‌کند که مسئول رسیدگی به تمام درخواست‌های ورودی است. این تضمین می‌کند که LM نخ‌های کافی برای رسیدگی به درخواست‌های همزمان از Orchestrator دارد.

اگر این ویژگی تنظیم نشده باشد، هر دو سرویس به طور پیش‌فرض روی مقدار 12 تنظیم می‌شوند.

روش پیکربندی

شما می‌توانید این ویژگی را در فایل BoardConfig.mk دستگاه خود با اضافه کردن آن به متغیر BOARD_BOOTCONFIG تنظیم کنید. این کار تضمین می‌کند که مقدار هر بار که دستگاه بوت می‌شود، اعمال می‌شود.

BOARD_BOOTCONFIG += \
    androidboot.sdv.max_bundles_management_threads=8

برای تغییر مقدار دستگاه خود، این خط را در فایل BoardConfig.mk مربوطه تغییر داده و آن را دوباره بسازید.

بهینه‌سازی زمان بوت

ro.sdv.orchestrator.state.ready یک ویژگی بولیِ write-once » است که بخشی از استراتژی بهینه‌سازی عملکرد زمان بوت است. این ویژگی نشان می‌دهد که عامل Orchestration مقداردهی اولیه خود را تکمیل کرده و آماده شروع مدیریت چرخه عمر بسته‌های خدماتی است. هدف اصلی آن اولویت‌بندی راه‌اندازی Orchestrator و بسته‌های خدماتی مدیریت‌شده آن با کنترل توالی راه‌اندازی سایر عامل‌های SDV است.

  • تنظیم شده توسط: نماینده ارکستراسیون.
  • چه زمانی: یک بار در طول فرآیند بوت شدن سیستم.
  • کاربرد: این ویژگی توسط سیستم init برای کنترل توالی راه‌اندازی اکثر عوامل SDV (مدیر به‌روزرسانی‌ها، ارائه‌دهنده VSIDL، مانیتور سلامت، کشف سرویس، تونل داده، RPC، VPM و تله‌متری) استفاده می‌شود. با شروع زودهنگام Orchestrator و منتظر گذاشتن سایر عوامل برای این ویژگی، سیستم تضمین می‌کند که Orchestrator می‌تواند وظیفه حیاتی خود یعنی شروع بسته‌های خدماتی را بدون رقابت برای منابع سیستم آغاز کند.

عملکرد

در طول بوت سیستم، شروع همزمان همه عامل‌ها می‌تواند منجر به رقابت در منابع شود و روند کلی بوت را کند کند. برای کاهش این مشکل، یک ترتیب راه‌اندازی متوالی با استفاده از ویژگی‌های سیستم اعمال می‌شود:

  1. رجیستری بسته‌های سرویس: ابتدا برای بارگذاری تمام فراداده‌های بسته سرویس شروع به کار می‌کند.
  2. مدیر چرخه حیات و هماهنگ‌کننده: این عوامل اصلی به محض آماده شدن رجیستری شروع به کار می‌کنند. این شروع زودهنگام بسیار مهم است زیرا به هماهنگ‌کننده اجازه می‌دهد تا ارزیابی پیکربندی خود را آغاز کرده و بلافاصله برای شروع بسته‌های خدماتی آماده شود.
  3. سایر عوامل SDV: فقط پس از آماده شدن Orchestrator شروع کنید.

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

حالت‌های مصرف‌شده توسط ارکستراتور

عامل هماهنگ‌سازی، اشتراک فعالی را در حالت‌های خودرو و توان ارسالی توسط VPM حفظ می‌کند. پس از برقراری اتصال اولیه بین هماهنگ‌کننده و سیستم مدیریت خودرو و توان (VPM)، هماهنگ‌کننده ویژگی‌های سیستم بولی زیر را روی true تنظیم می‌کند:

  • sdv.orchestrator.bootup.power_mode.ready

  • sdv.orchestrator.bootup.vehicle_mode.ready

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

وضعیت خودرو و قدرت

عامل مدیریت حالت خودرو و توان (VPM) به اجزای SDV این امکان را می‌دهد که از وضعیت فعلی خودرو، مانند حالت عملیاتی (مثلاً در حالت پارک یا رانندگی) و وضعیت توان (مثلاً روشن و معلق) مطلع شوند. هماهنگ‌کننده (Orchestrator) این مقادیر را ارزیابی می‌کند تا مشخص کند کدام بسته‌های خدماتی باید بر اساس پیکربندی هماهنگ‌کننده اجرا شوند. برای کسب اطلاعات بیشتر، به بخش مدیریت خودرو و توان مراجعه کنید.

حالت‌های سفارشی

با توجه به تعداد حالت‌های خودرو، نمی‌توانیم همه آنها را مدل‌سازی کنیم. هر تولیدکننده اصلی تجهیزات (OEM) نیازهای متفاوتی دارد و استانداردسازی حالت‌های خودرو نمی‌تواند همه موارد استفاده تولیدکننده اصلی تجهیزات (OEM) را پوشش دهد. در نتیجه، ما از حالت‌های خاص تولیدکننده اصلی تجهیزات (OEM) که به عنوان حالت‌های سفارشی شناخته می‌شوند، پشتیبانی می‌کنیم. این حالت‌ها حالت‌های خودرو و قدرت موجود را گسترش نمی‌دهند. در عوض، آنها راهی برای تعریف حالت‌های جدید فراهم می‌کنند.

عملکرد:

  • دامنه سراسری: حالت‌های سفارشی سراسری هستند و به طور یکنواخت در تمام ماشین‌های مجازی مدیریت شده توسط Orchestrator اعمال می‌شوند.

  • ترکیب: هر تغییر حالت سفارشی از دو عنصر تشکیل شده است:

    • نام: شناسه منحصر به فردی که توسط تولیدکننده اصلی تجهیزات (OEM) برای نمایش حالت سفارشی انتخاب شده است.

    • مقدار: وضعیت فعلی برای حالت سفارشی، که در صورت عدم تنظیم مقدار، می‌تواند UNDEFINED باشد.

  • نقش هماهنگ‌کننده: هماهنگ‌کننده به عنوان یک گیرنده غیرفعال مقادیر حالت سفارشی عمل می‌کند.

  • نقش بسته سرویس: هر بسته سرویس می‌تواند چندین حالت سفارشی داشته باشد و می‌تواند مقادیر جدیدی را به هر کدام منتشر کند. چندین بسته سرویس می‌توانند یک حالت سفارشی یکسان داشته باشند، به این معنی که یک حالت سفارشی می‌تواند مقادیر جدیدی را از منابع مختلف دریافت کند.

  • مسئولیت اعتبارسنجی: تولیدکنندگان اصلی تجهیزات (OEM) مسئول تضمین انتقال وضعیت معتبر هستند. هماهنگ‌کننده (Orchestrator) هر مقدار جدیدی را می‌پذیرد.

ویژگی‌های تخمینی:

  • تعداد تخمینی: حالت‌های قدرت و خودرو، چرخه عمر اکثر بسته‌های خدماتی را مدیریت می‌کنند و حالت‌های سفارشی نقش تکمیلی دارند. ما انتظار داریم که تعداد حالت‌های سفارشی به ده‌ها و نه صدها مورد برسد.

  • زمان‌بندی تخمینی: حالت‌ها به صورت دوره‌ای ارسال نمی‌شوند. در عوض، حالت‌ها رویدادمحور هستند و توسط اقدامات خاصی مانند باز کردن در، شروع توالی پارکینگ، شروع چرخه شارژ و سایر رویدادهای مشابه با اهمیت تعریف شده توسط OEM فعال می‌شوند.

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

حالت‌های پشتیبانی‌شده

برای اطمینان از اینکه بسته‌های سرویس فقط در حالت‌های سفارشی که خودشان دارند منتشر می‌شوند، هر کدام باید فهرست حالت‌های سفارشی متعلق به خود را به صراحت در پیکربندی Orchestrator خود اعلام کنند، که در ماشین مجازی محلی با رجیستری بسته سرویس موجود است. تلاش برای انتشار در یک حالت سفارشی اعلام نشده رد می‌شود.

برای اعلام حالت‌های سفارشی که یک بسته سرویس مجاز به انتشار آنهاست (و از این رو مالک آن است)، طرحواره اولیه service_bundle_config با موارد زیر گسترش می‌یابد:

// Service bundle configuration.
//
// Defines service bundle metadata, its instances, and configuration for instances
// lifecycle states depending on the state of the vehicle.
message ServiceBundleConfig {
      [...]

    // The list of custom modes that this service bundle publishes.
    repeated string custom_mode = 5;
}

پیکربندی بسته‌ها بر اساس حالت‌ها

پیکربندی اولیه Orchestrator موجود (کامپوننت Condition ) از دستکاری بسته‌های سرویس بر اساس حالت‌های سفارشی پشتیبانی می‌کند:

message Condition {
  oneof root {
    string power_state = 1;
    string vehicle_state = 2;
    CustomState custom_state = 3;
    Condition not = 4;
    Expression and = 5;
    Expression or = 6;
  }
}

message CustomState {
  // Custom mode being checked.
  string mode = 1;
  // State of the custom mode.
  string state = 2;
}

نمونه اولیه

مثال زیر نحوه پیکربندی نمونه‌هایی از یک بسته سرویس را برای شروع بر اساس وضعیت TURN و FOG نشان می‌دهد:

service_bundle_config {
package_name: "oem.package"
service_bundle_name: "OemApplication"
instance: "flasher_light"
// Service bundle is allowed to set values for the TURN mode
custom_mode: "TURN"
// Service bundle is allowed to set values for the FOG mode
custom_mode: "FOG"

state {
    condition {
        custom_state {
            mode: "TURN"
            state: "LEFT"
        }
    }
    instances_states {
        started: "flasher_light"
    }
}

state {
    condition {
        custom_state {
            mode: "FOG"
            state: "ON"
        }
    }
    // Group assumed to be defined containing all FOG lights instances.
    groups_states {
        started: "fog_lights"
    }
}

}

حالت‌های سفارشی جدید را تنظیم کنید

فرآیند تنظیم یک مقدار حالت سفارشی جدید با بسته سرویس آغاز می‌شود، که مقدار مورد نظر را به Orchestrator محلی که روی همان ماشین مجازی اجرا می‌شود، ارسال می‌کند. سپس Orchestrator تأیید می‌کند که بسته سرویس مجوزهای لازم برای انتشار در حالت سفارشی مشخص شده را دارد و با ارجاع به پیکربندی تعریف شده در .textproto ، تعیین می‌کند که آیا باید مقدار را به سایر ماشین‌های مجازی منتشر کند یا خیر. پس از انتشار، هر Orchestrator پیکربندی خود را بررسی می‌کند تا لیستی از بسته‌های سرویس را که وضعیت آنها باید تغییر کند، پیدا کند.

آر پی سی

هر Orchestrator که روی هر ماشین مجازی اجرا می‌شود، یک سرور RPC ایجاد می‌کند تا به مقادیر حالت سفارشی جدید گوش دهد. هر بسته سرویس که می‌خواهد یک حالت سفارشی را به‌روزرسانی کند، باید یک کلاینت RPC برای سرور ایجاد کند. ACLها برای جلوگیری از اتصال بسته‌های غیرمجاز به سرور اعمال می‌شوند.

تعریف اولیه برای تنظیم یک مقدار جدید از طریق RPC مانند این مثال است:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

package com.sdv.google.Orchestrator;

// Representation of the request used by service bundles to update a custom mode.
// Service bundles are permitted to update only the custom modes specifically designated
// for them within the Orchestrator configuration.
message SetCustomStateRequest {
  // Required.
  // The name of the custom mode.
  // The mode string can not be longer than 56 characters and can only contain
  // letters, numbers, dashes, dots and underscores: [a-zA-Z0-9_-.].
  // No other special character nor spaces should be present in the mode.
  string mode = 1;

  // Required.
  // The new value for the custom mode.
  // The value string can not be longer than 56 characters and can only contain
  // letters, numbers, dashes, dots and underscores: [a-zA-Z0-9_-.].
  // No other special character nor spaces should be present in the value.
  string value = 2;

  // Required.
  // The timestamp in which the new custom mode value was set. This is used to
  // prevent race conditions whenever different service bundles in different
  // VMs want to set a new value for the same custom mode.
  // We use this timestamp to order the requests and we promise eventual
  // consistency: while temporary inconsistencies may occur, the system will
  // eventually converges to the correct state.
  .google.protobuf.Timestamp timestamp = 3;
}

// Representation of the set custom state response.
message SetCustomStateResponse {}

// Orchestrator interface for service bundles that update the value of a
// custom mode.
// When a new value is received, it is propagated to Orchestrators running on
// other VMs.
service CustomStateService {
  // Updates the value for the custom mode.
  // Returns the error:
  // - PermissionDenied: the service is not authorized to update the custom mode.
  // - InvalidArgument: the provided mode and/or value are not valid.
  rpc SetCustomState(SetCustomStateRequest) returns (SetCustomStateResponse) {};
}

لغو انتقال قدرت

ارکستراتور (Orchestrator) از طریق حالت برق SHUTDOWN_CANCELLED (که توسط VPM به ارکستراتور ارسال می‌شود) امکان لغو انتقال‌های برق جاری را فراهم می‌کند.

به عنوان مثال، پیکربندی Orchestrator زیر را در نظر بگیرید:

state {
    condition {
        power_state: "SUSPEND_TO_RAM_ENTER"
    }
    instances_states {
        started: "instance-1"
        started: "instance-2"
        started: "instance-3"
    }
}

وقتی حالت SHUTDOWN_CANCELLED دریافت می‌شود، دو سناریوی اصلی رفتار Orchestrator را تعیین می‌کنند. در هر دو مورد، حالت قدرت SHUTDOWN_CANCELLED به انتهای صف اضافه می‌شود. سپس SHUTDOWN_CANCELLED پس از مصرف عناصر صف اجرا می‌شود.

سناریو ۱: حالت فعلی در حال انجام، حالت مصرف برق است

اگر Orchestrator در حال اجرای به‌روزرسانی حالت power باشد، درخواست لغو حالت in-progress (در حال انجام) می‌شود. در حالی که Lifecycle Manager ذاتاً از لغو انتقال in-progress پشتیبانی نمی‌کند، Orchestrator تأیید می‌کند که هیچ درخواست بسته سرویس جدیدی آغاز نشده باشد.

مثال: اگر instance-1 از پیکربندی مثال قبلی در حال شروع به کار باشد، زمانی که حالت SHUTDOWN_CANCELLED دریافت می‌شود، instance-1 راه‌اندازی خود را تکمیل می‌کند. با این حال، instance-2 و instance-3 به حالت شروع شده منتقل نمی‌شوند.

سناریو ۲: یک حالت مصرف برق در صف پردازش وجود دارد

در حالتی که Orchestrator در حال پردازش به‌روزرسانی حالت غیربرق است و درخواست برق در صف حالت‌هایی که باید اجرا شوند وجود دارد، انتقال برق از صف حذف می‌شود. این امر مانع از اجرای آن می‌شود.

مثال: با استفاده از پیکربندی مثال قبلی، اگر Orchestrator روی یک به‌روزرسانی غیرمرتبط با برق (مانند به‌روزرسانی خودرو) کار کند و SUSPEND_TO_RAM_ENTER در صف باشد، دریافت SHUTDOWN_CANCELLED منجر به شروع نشدن هیچ یک از نمونه‌ها ( instance-1 ، instance-2 ، instance-3 ) نمی‌شود.

نمونه پیاده‌سازی

کاتالوگ برای کلاینتی که می‌خواهد از کد تولید شده توسط میان‌افزار برای ایجاد یک کلاینت به سرور RPC استفاده کند، می‌تواند مانند این مثال باشد:

# proto-file: //system/software_defined_vehicle/vsidl/language/src/protos/sdv/vsidl/v1/syntax.proto
# proto-message: VsidlEntry

package: "package_name"

service_bundle {
    name: "service_bundle_name"

    client {
        service: "com.android.sdv.orchestrator.CustomStateService"
    }
}

هنگام تولید کد، باید وابستگی را به کاتالوگ Orchestrator اضافه کنید:

--dependency-catalog-path orchestration/engine/stable/vsidl/*

کد کلاینت برای ارسال یک مقدار جدید به صورت زیر است:

let fqin = ServiceFqin::builder()
        .sdv_vm_name("vm_name")
        .sdv_package_name("package_name")
        .service_bundle_name("service_bundle_name")
        .service_instance_name("instance_name")
        .build()
        .unwrap();
let context_ref = ContextRef::create(fqin);
let comms = Arc::new(SdvComms { context: context_ref });
// service_bundle_name is the bundle generated with middleware code that defines
// the RPC client to "com.android.sdv.orchestrator.CustomStateService".
let client = service_bundle_name::new(comms).await.unwrap();
let rpc_client = client
        .create_rpc_client::<Client>(
            UnitName::builder()
                .vm_name(comms.context.get_self_fqin().get_sdv_vm_name())
                .package_name("com.android.sdv.orchestrator")
                .bundle_name("OrchestratorServiceBundle")
                .service_unit_name(Client::DEFAULT_UNIT_NAME)
                .build()
                .unwrap(),
            ClientOptions::default(),
        )
        .await;
let client = Arc::new(rpc_client.unwrap());
let request = SetCustomStateRequest {
mode: custom_mode_name,
value: custom_mode_value,
timestamp: MessageField::some(Timestamp::now()),
..Default::default()
};
let result = client.SetCustomState(&request).await;
// Process result

ابزارهای اشکال‌زدایی

عامل Orchestrator از ابزار dumpsys پشتیبانی می‌کند. می‌توانید با اجرای دستور زیر روی یک نمونه SDV در حال اجرا، آن را فراخوانی کنید:

adb shell dumpsys com.google.sdv.ISdvAgent/orch

از این ابزار برای اشکال‌زدایی و کسب بینش در مورد وضعیت داخلی عامل Orchestrator استفاده کنید. انجام این کار موارد زیر را نمایش می‌دهد:

  • وضعیت حالت‌های فعلی: وضعیت فعال خودرو، قدرت و حالت‌های سفارشی را مشاهده کنید.
  • ناشران حالت سفارشی: مشخص کنید کدام سرویس‌ها می‌توانند حالت‌های سفارشی را منتشر کنند (و به کدام حالت‌ها).
  • وضعیت مورد نیاز برای هر سرویس: وضعیت هر بسته سرویس را بر اساس شرایط از پیش تعریف شده و حالت‌های فعلی بررسی کنید. این به تشخیص اینکه چرا یک سرویس ممکن است در وضعیت مورد انتظار نباشد، کمک می‌کند.
  • وضعیت اجرای حالت: تصویر واضحی از حالت اجرایی در حال اجرا یا آخرین حالت اجرایی در صورت عدم وجود حالت در حال اجرا، دریافت کنید.
  • صف اجرای حالت: مشاهده حالت‌های منتظر اجرا.

برای مثال:

AGENT NAME: SDV Agent dump - Orchestrator
AGENT FQIN: instance1:com.android.sdv.orchestrator.OrchestratorServiceBundle/default
AGENT STATE: See orchestrator state below.
----------------
----------------
INTERNAL STATE REPORTERS:

*NAME: Configuration state
*REPORT:
Active modes:
MODE                          VALUE                         TIMESTAMP (scs, ns)
Power                         POWER_OFF_EXIT                -
Vehicle                       VEHICLE_ON                    -
Custom("CHARGING")            ON                            1750757590 (scs) 466507459 (ns)
Custom("TIRE_PRESSURE")       front-left                    1750757570 (scs) 554522995 (ns)

Modes allowed to publish by bundle (FQIN: modes):
com.android.sdv.sample.orchestration/CustomModeControlBundle: CHARGING, TIRE_PRESSURE

Requested state for instances:
STATE          FQIN
Started        com.android.sdv.sample.orchestration/CustomModeControlBundle/always-started-instance
Started        com.android.sdv.sample.orchestration/OrchestratedServiceBundle/my-instance
Started        com.sdv.oem.sample.diagnostics/DiagnosticsSampleWithDataItem/instance
Started        com.sdv.oem.sample.diagnostics/DiagnosticsSampleWithEvent/instance
Started        com.sdv.oem.user_preferences/UserPreferencesServiceBundle/default
----------------
*NAME: Engine state
*REPORT:
Last mode enforced was Custom("CHARGING") with value "ON"

Next modes to process: []
----------------

برای کسب اطلاعات بیشتر در مورد بسته‌های خدماتی جداگانه که توسط Orchestrator مدیریت می‌شوند، از dumpsys موجود در Lifecycle Manager به شرح زیر استفاده کنید:

dumpsys google.sdv.lifecycle.ILifecycleManager/default

انجام این کار اطلاعات دقیقی در مورد وضعیت چرخه حیات هر سرویس ارائه می‌دهد. با ترکیب خروجی Orchestrator dumpsys با خروجی Lifecycle Manager، تصویر کاملی از چرخه حیات بسته‌های سرویس در ماشین مجازی ارائه می‌شود.