



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-99f877e9ddfc0e51.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-48fdd0811afbab3c.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-79ad2ace604703b3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-24484a076f02295f.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-99f877e9ddfc0e51.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-48fdd0811afbab3c.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-f4bf1142976e4bbf.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-f661b49995ba0bd8.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-0b38d22346321c92.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-f1c62c9e70259b9f.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-79ad2ace604703b3.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-24484a076f02295f.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-f50cacf0a86b9929.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-e61d4f4ca17852c2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-39c10993d5603fac.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-73236c840c0c7d90.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-0de76f07cc035b10.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-fd1500c8744e40d6.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-ed9ca172356fd545.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-1d2c7f7b52a6068b.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-54ba76e934a49d7c.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-456bd5deb85c7ecd.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-11ee8a031c040c1a.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-2d56bdb0166c0238.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_header_reorder","copilot_chat_max_upsell","copilot_chat_minimize_contextual","copilot_chat_models_browser_cache","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_embedded_header_button","copilot_immersive_file_preview_keep_mounted","copilot_immersive_suggestion_pills","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_agents_repository_enablement","copilot_mission_control_early_stop","copilot_mission_control_environment_list_icons","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_repo_hovercards","copilot_mission_control_sandbox_client_side_clone","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_session_filters","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_pr_chat_enhancements","copilot_prominent_upgrade_button","copilot_resource_panel","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset","copilot_workbench_sunset_redirect","copilot_workbench_ubb","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","glc_code_quality_repo_settings_workflow_config","hide_github_models_ui","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_optimistic_updates","issue_relative_time_micro","issues_dashboard_sso_structured_errors","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_lazy_load_comment_box_suggestions","issues_optimistic_linked_branch_create","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_lazy_hydrate_agent_tasks","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_checks_refetch_dedupe","merge_status_header_feedback","oauth_authorize_clickjacking_protection","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_commit_checks_dialog","pull_request_copilot_attribution_header","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_feedback_dialog","pull_request_virtualization_image_estimate","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_persistence","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_banner_learn_copilot_sdk","site_global_nav_spark_models_removed","spark_prompt_secret_scanning","spark_server_connection_status","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","ui_service_compute_proxy_control","ui_service_referrer_metrics","ui_service_staleness_detection","update_issue_suggestions","user_code_paste_ux","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workbench_store_readonly","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-e3d808ee18eb9784.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-a8b022a5e8030e5b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-74e9766bd696d26a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-eed8df9c2267c378.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-5305162aa9984914.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-cd1b421ad0ad7ed5.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-80ac20cf64889c3e.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.94e436d05b4d028c.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-86a8f5de995615f8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e88088f989b27670.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-7cdf4e0db98b997c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-6b3c07383371bf58.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-36f036c13c2e3a4c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/kw-866fd9513ae95106.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/r1-b075aab3204f32f9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7c5d1669717041f8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-5126390ff433704d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j05-dce4d588268f0f7e.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-1351a539d75a0c16.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-cf488a6c99a7db67.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-f3f5d71440009c48.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-76b18916d0c8ec4d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-5109c77d7ac61078.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-fbb00aaa3ab9abdf.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/04n-51c49ba758739f13.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-024971cb63acad59.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-364e19c63d726e9a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6ny-c969fbae697a356f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/yhq-3a209035a30b1a09.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/z1v-da5b33b877bfa358.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-09f85d22a6c8931b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9y-81cfe57dc9040f3e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-41a4cf04cbd99503.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0p-81491ed0d9d666e2.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-5be29509910db315.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.5858534b1c27f133.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-c82d80917a2ff48a.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-12ebdc24dcff1ecc.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-9a860680a5f230b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-363f0ebf4f62f310.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-bf6f21d7e7a43c35.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fe-7576d9b281e2106a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wsr-5fd3071e5a9061ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0n-ecadb2ffe6b01ba2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xv-51cb34754bda73a9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-6317ce1c31aed1db.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-d90ce3a169b741ed.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-de176c4ee471f2b3.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/eag-d9eea130fa716df9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y2-87df441f1bc5a264.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/kcz-607e36c8a3751cf0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/x4-65dba777efd828f3.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gzu-1a09248f686325f6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/on-95be29ba1ef725d9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi0-e2f78de823e39ca9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-1dbc371cef78c3c1.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l5-c4edb8ab48c5846d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2z-c92998400310b94b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-038758dcbfe08dab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0k-b7df0a74912a42bf.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-2bbb73a69162e23b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-93ae8b358505d372.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b9-69d9b60a1b1fcd59.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ec-ec74cb1fa6c31a3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-a401e69a37d95bcc.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-6accb9e40c25a6a5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-0a2e46387735f1f4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-cb1e4ddbce4f007b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-9f5235d335ab624b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ko6-9e80f7ac359e3c43.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/uw-8c275f7ac25b7cf6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bsb-4f4ac8c20da73fac.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/w5-13e3a7548bb20af9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fm-53dde3bf12947bbf.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/z-45022d3da7b8817e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/h0-010921512138e12f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/5p-ae5db0820116fb43.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8vq-b2af216e992e11ef.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/g5-b399ce875f8bd326.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-f5d51b571cd317cb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/arw-51e8918a1b75a80f.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-d6817f7f39966a5b.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.9d59d1018a52a53c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.bd9e6b542f167fd8.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/z.812a998e1961b84d.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.13e027137438fd9f.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.b231d2fa1de61895.module.css" />

  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hu-1fc0b2a167afc025.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fbr-9cd34ba01ef26edb.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-947ac5d131e3fcb0.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.9d59d1018a52a53c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.b6edc42656f15042.module.css" />


  <title>leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:5ef11633-7870-2dcf-783e-060a10aa378a">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="A9E8:320682:E17AB9D:D22C9DC:6AAC34CE" data-pjax-transient="true"/><meta name="html-safe-nonce" content="03ea24bd1eba938c6ac8ea82e0fdeb541619c8f28926de1383a858543a87d331" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBOUU4OjMyMDY4MjpFMTdBQjlEOkQyMkM5REM6NkFBQzM0Q0UiLCJ2aXNpdG9yX2lkIjoiMTk4NDM4MDYwODg2NjY5NDM1MCIsInJlZ2lvbl9lZGdlIjoiZnJhIiwicmVnaW9uX3JlbmRlciI6ImZyYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="59850d8cd26ebfb4346a236d0cbfbc3bb099f6004ef95cf0b8a1a11f859824dc" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:168900469" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="Solving LeetCode problems in the best way. Python, Java, C++, JavaScript, C#, Go, Ruby, Rust, C, Kotlin, Swift, PHP, and Dart are supported! Official website👇🏻: - leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/e8a4c030e49610dd06eae7a5af0bb98a981a070f0d30c9988471115fd294d4a2/leetcode-python-java/leetcode-python-java" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java" /><meta name="twitter:description" content="Solving LeetCode problems in the best way. Python, Java, C++, JavaScript, C#, Go, Ruby, Rust, C, Kotlin, Swift, PHP, and Dart are supported! Official website👇🏻: - leetcode-python-java/leetcode-pyth..." />
  <meta property="og:image" content="https://opengraph.githubassets.com/e8a4c030e49610dd06eae7a5af0bb98a981a070f0d30c9988471115fd294d4a2/leetcode-python-java/leetcode-python-java" /><meta property="og:image:alt" content="Solving LeetCode problems in the best way. Python, Java, C++, JavaScript, C#, Go, Ruby, Rust, C, Kotlin, Swift, PHP, and Dart are supported! Official website👇🏻: - leetcode-python-java/leetcode-pyth..." /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java" /><meta property="og:url" content="https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md" /><meta property="og:description" content="Solving LeetCode problems in the best way. Python, Java, C++, JavaScript, C#, Go, Ruby, Rust, C, Kotlin, Swift, PHP, and Dart are supported! Official website👇🏻: - leetcode-python-java/leetcode-pyth..." />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="c282ab8d18bf3ecaaea252f262bee1e40b03b59bde00f36fcff2963bbc274a0b" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="0c5c6e5334a905d8f9521e09eadcffba484d422e0d262e07ff922e6bc18b2ac6" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="ec4c7b86d7b57240253150b827ea48b04e08d8760dc6553d2a04f62000f3fe0c" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="8586b8303e9a7a8be5d51d6f88ed14d2d50547e7394b9142b7c7c70efc96ff5c" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/leetcode-python-java/leetcode-python-java git https://github.com/leetcode-python-java/leetcode-python-java.git">

  <meta name="octolytics-dimension-user_id" content="204447696" /><meta name="octolytics-dimension-user_login" content="leetcode-python-java" /><meta name="octolytics-dimension-repository_id" content="168900469" /><meta name="octolytics-dimension-repository_nwo" content="leetcode-python-java/leetcode-python-java" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="168900469" /><meta name="octolytics-dimension-repository_network_root_nwo" content="leetcode-python-java/leetcode-python-java" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="15054c636efee85287b9bc96e3bb2d1f9043f550" data-turbo-track="reload">
  <meta name="ui-target" content="full">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/l7j-2ddd8b435dadae28.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-325e2b43d98ba4eb.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.9d59d1018a52a53c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.1b5891147d3a9181.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          
          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-8671acba87bc0dcb.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/i26-f2ae65b837c90ae7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz5-23f28c0f388769c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/lht-26506ea833dda5be.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p1-76a75a6081059b19.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d8-bbc4e3ce35fac150.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-c4ca62c5e0e0318e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4s-c22d880230690e1f.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-8180d9dbe291a784.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.9d59d1018a52a53c.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.6a01c236ff527e7e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/4s.e3d02f110161be52.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fleetcode-python-java%2Fleetcode-python-java%2Fblob%2Fmaster%2FREADME.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=leetcode-python-java%2Fleetcode-python-java","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md\",\"user_id\":null}}","auth_hydro_click_hmac":"753a5e10af07c7ccd315b4881e831ebc81bfce49724c457508b914200f847e2a","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fleetcode-python-java%2Fleetcode-python-java%2Fblob%2Fmaster%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="753a5e10af07c7ccd315b4881e831ebc81bfce49724c457508b914200f847e2a"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fleetcode-python-java%2Fleetcode-python-java%2Fblob%2Fmaster%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="753a5e10af07c7ccd315b4881e831ebc81bfce49724c457508b914200f847e2a"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=leetcode-python-java%2Fleetcode-python-java" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="753a5e10af07c7ccd315b4881e831ebc81bfce49724c457508b914200f847e2a"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-af7d8ae0-08d2-4dee-8ee4-3778f6e41226" aria-labelledby="tooltip-a23c51bb-753c-46ed-b1c6-7c18f39d39c2" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-a23c51bb-753c-46ed-b1c6-7c18f39d39c2" for="icon-button-af7d8ae0-08d2-4dee-8ee4-3778f6e41226" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>





  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      
    


    








  

    <div id="repository-container-header"  class="tmp-pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace>

        <div class="d-flex flex-nowrap flex-justify-end tmp-mb-3  tmp-px-3 tmp-px-lg-5" style="gap: 1rem;">

          <div class="flex-auto min-width-0 width-fit">
              
  <div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2 tmp-mr-2">
    <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path>
</svg>
    
    <span class="author flex-self-stretch" itemprop="author">
      <a class="url fn" rel="author" data-hovercard-type="organization" data-hovercard-url="/orgs/leetcode-python-java/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/leetcode-python-java">
        leetcode-python-java
</a>    </span>
    <span class="mx-1 flex-self-stretch color-fg-muted">/</span>
    <strong itemprop="name" class="mr-2 flex-self-stretch">
      <a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/leetcode-python-java/leetcode-python-java">leetcode-python-java</a>
    </strong>

    <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span>
  </div>


          </div>

          <div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;">
              <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;">
    
      

  <li>
            <a href="/login?return_to=%2Fleetcode-python-java%2Fleetcode-python-java" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="7cfb684fa80016927f64fa302f0b47d6c21bc1d53d09f725e2982aeb9353e06d" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2 tmp-mr-2">
    <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path>
</svg>Notifications
</a>    <tool-tip id="tooltip-5cceae50-0b27-4fe8-93e1-df28d61c074b" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip>

  </li>

  <li>
          <a icon="repo-forked" id="fork-button" href="/login?return_to=%2Fleetcode-python-java%2Fleetcode-python-java" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:168900469,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="560b93ace0979b690505aaa0ca2355a03aac73e3d4991cb844634c46ff5cc834" data-view-component="true" class="btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2 tmp-mr-2">
    <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>
</svg>Fork
    <span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="40" data-view-component="true" class="Counter">40</span>
</a>
  </li>

  <li>
        <div data-view-component="true" class="BtnGroup d-flex">
        <a href="/login?return_to=%2Fleetcode-python-java%2Fleetcode-python-java" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:168900469,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="4ea4a06eacf7e6105f4753e81deaf372ed84c38219df7a89e185d3856de8f420" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2 tmp-mr-2">
    <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
</svg><span data-view-component="true" class="d-inline">
          Star
</span>          <span id="repo-stars-counter-star" aria-label="300 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="300" data-view-component="true" class="Counter js-social-count">300</span>
</a></div>
  </li>

</ul>

          </div>
        </div>

          <div id="responsive-meta-container" data-turbo-replace>
</div>


            <nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 tmp-px-3 px-md-4 tmp-px-md-4 px-lg-5 tmp-px-lg-5">

  <ul data-view-component="true" class="UnderlineNav-body list-style-none">
      <li data-view-component="true" class="d-inline-flex">
  <a id="code-tab" href="/leetcode-python-java/leetcode-python-java/tree/master" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /leetcode-python-java/leetcode-python-java/tree/master" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-command-id="repositories:go-to-code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline">
    <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
        <span data-content="Code">Code</span>
          <span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="issues-tab" href="/leetcode-python-java/leetcode-python-java/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /leetcode-python-java/leetcode-python-java/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-command-id="repositories:go-to-issues" data-react-nav="issues-react" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline">
    <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
        <span data-content="Issues">Issues</span>
          <span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="pull-requests-tab" href="/leetcode-python-java/leetcode-python-java/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /leetcode-python-java/leetcode-python-java/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-command-id="repositories:go-to-pull-requests" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline">
    <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
        <span data-content="Pull requests">Pull requests</span>
          <span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="actions-tab" href="/leetcode-python-java/leetcode-python-java/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /leetcode-python-java/leetcode-python-java/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-command-id="repositories:go-to-actions" data-react-nav="actions-workflows" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline">
    <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
        <span data-content="Actions">Actions</span>
          <span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="projects-tab" href="/leetcode-python-java/leetcode-python-java/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /leetcode-python-java/leetcode-python-java/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-command-id="repositories:go-to-projects" data-react-nav="repo" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline">
    <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
        <span data-content="Projects">Projects</span>
          <span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="security-and-quality-tab" href="/leetcode-python-java/leetcode-python-java/security" data-tab-item="i5security-and-quality-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /leetcode-python-java/leetcode-python-java/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-command-id="repositories:go-to-security" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security and quality&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline">
    <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span data-content="Security and quality">Security and quality</span>
          <span id="security-and-quality-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="insights-tab" href="/leetcode-python-java/leetcode-python-java/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /leetcode-python-java/leetcode-python-java/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-command-id="repositories:go-to-insights" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline">
    <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
        <span data-content="Insights">Insights</span>
          <span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
</ul>
    <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 tmp-pr-3 pr-md-4 tmp-pr-md-4 pr-lg-5 tmp-pr-lg-5 right-0">      <action-menu data-select-variant="none" data-view-component="true">
  <focus-group direction="vertical" mnemonics retain>
    <button id="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-button" popovertarget="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-overlay" aria-controls="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-list" aria-haspopup="true" aria-labelledby="tooltip-01299921-5fb9-41ad-ba3c-4c60cae209bf" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual">
    <path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path>
</svg>
</button><tool-tip id="tooltip-01299921-5fb9-41ad-ba3c-4c60cae209bf" for="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip>


<anchored-position data-target="action-menu.overlay" id="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-overlay" anchor="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true">
  <div data-view-component="true" class="Overlay Overlay--size-auto">
    
      <div data-view-component="true" class="Overlay-body Overlay-body--paddingNone">          <action-list>
  <div data-view-component="true">
    <ul aria-labelledby="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-button" id="action-menu-f37677ad-cc37-4177-a277-a6c678b1c8e0-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap">
        <li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-c2630183-8823-4963-871b-40515f75be1c" href="/leetcode-python-java/leetcode-python-java/tree/master" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code">
    <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Code
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-6bbf0213-9839-4f3d-8b50-db3794337299" href="/leetcode-python-java/leetcode-python-java/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened">
    <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Issues
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-2a4cbcd3-d4d1-4410-9a45-4bb099133e0d" href="/leetcode-python-java/leetcode-python-java/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request">
    <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Pull requests
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-6808dd52-15ab-4cb2-bded-e255d90671f0" href="/leetcode-python-java/leetcode-python-java/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play">
    <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Actions
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-2c51fb7f-9fa7-4177-bce3-ef059f6b48c3" href="/leetcode-python-java/leetcode-python-java/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table">
    <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Projects
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i5security-and-quality-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-cebe33cd-817a-4730-8afc-2d4c579c27b5" href="/leetcode-python-java/leetcode-python-java/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield">
    <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Security and quality
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-203f8fa0-a52e-4619-ab48-dd7738d3da43" href="/leetcode-python-java/leetcode-python-java/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph">
    <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Insights
</span>      
</a>
  
</li>
</ul>    
</div></action-list>


</div>
      
</div></anchored-position>  </focus-group>
</action-menu></div>
</nav>

    </div>
  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/leetcode-python-java/leetcode-python-java/blob/master/README.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"Learn-Rails-by-Reading-Source-Code","anchor":"learn-rails-by-reading-source-code","htmlText":"Learn-Rails-by-Reading-Source-Code"},{"level":2,"text":"Table of Contents","anchor":"table-of-contents","htmlText":"Table of Contents"},{"level":2,"text":"Part 0: Before reading Rails 5 source code","anchor":"part-0-before-reading-rails-5-source-code","htmlText":"Part 0: Before reading Rails 5 source code"},{"level":3,"text":"What will you learn from this tutorial?","anchor":"what-will-you-learn-from-this-tutorial","htmlText":"What will you learn from this tutorial?"},{"level":2,"text":"Part 1: Your app: an instance of YourProject::Application","anchor":"part-1-your-app-an-instance-of-yourprojectapplication","htmlText":"Part 1: Your app: an instance of YourProject::Application"},{"level":2,"text":"Part 2: config","anchor":"part-2-config","htmlText":"Part 2: config"},{"level":2,"text":"Part 3: Every request and response","anchor":"part-3-every-request-and-response","htmlText":"Part 3: Every request and response"},{"level":3,"text":"Puma","anchor":"puma","htmlText":"Puma"},{"level":3,"text":"Rack apps","anchor":"rack-apps","htmlText":"Rack apps"},{"level":3,"text":"The core app: ActionDispatch::Routing::RouteSet instance","anchor":"the-core-app-actiondispatchroutingrouteset-instance","htmlText":"The core app: ActionDispatch::Routing::RouteSet instance"},{"level":3,"text":"Render view","anchor":"render-view","htmlText":"Render view"},{"level":3,"text":"How can instance variables defined in Controller be accessed in view file?","anchor":"how-can-instance-variables-defined-in-controller-be-accessed-in-view-file","htmlText":"How can instance variables defined in Controller be accessed in view file?"},{"level":2,"text":"Part 4: What does $ rails server do?","anchor":"part-4-what-does--rails-server-do","htmlText":"Part 4: What does $ rails server do?"},{"level":3,"text":"Thor","anchor":"thor","htmlText":"Thor"},{"level":3,"text":"Rails::Server#start","anchor":"railsserverstart","htmlText":"Rails::Server#start"},{"level":3,"text":"Starting Puma","anchor":"starting-puma","htmlText":"Starting Puma"},{"level":3,"text":"Conclusion","anchor":"conclusion","htmlText":"Conclusion"},{"level":3,"text":"Exiting Puma","anchor":"exiting-puma","htmlText":"Exiting Puma"},{"level":4,"text":"Process and Thread","anchor":"process-and-thread","htmlText":"Process and Thread"},{"level":5,"text":"Example one","anchor":"example-one","htmlText":"Example one"},{"level":5,"text":"Example two","anchor":"example-two","htmlText":"Example two"},{"level":4,"text":"Send SIGTERM to Puma","anchor":"send-sigterm-to-puma","htmlText":"Send SIGTERM to Puma"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLearn-Rails-by-Reading-Source-Code\u003c/h1\u003e\u003ca id=\"user-content-learn-rails-by-reading-source-code\" class=\"anchor\" aria-label=\"Permalink: Learn-Rails-by-Reading-Source-Code\" href=\"#learn-rails-by-reading-source-code\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://github.com/996icu/996.ICU/blob/master/LICENSE\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/be80b8cb211ceb2263744e99fdb161a40124901906fd7c7f47d6361760dd7e8b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d416e74692532303939362d626c75652e737667\" alt=\"LICENSE\" data-canonical-src=\"https://img.shields.io/badge/license-Anti%20996-blue.svg\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://996.icu\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/ac8f294a80f65338db545230f1a881b9a382204a1f187c6ff40ee679d42d40ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c696e6b2d3939362e6963752d7265642e737667\" alt=\"996.icu\" data-canonical-src=\"https://img.shields.io/badge/link-996.icu-red.svg\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTable of Contents\u003c/h2\u003e\u003ca id=\"user-content-table-of-contents\" class=\"anchor\" aria-label=\"Permalink: Table of Contents\" href=\"#table-of-contents\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#part-0-before-reading-rails-5-source-code\"\u003ePart 0: Before reading Rails 5 source code\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#what-will-you-learn-from-this-tutorial\"\u003eWhat will you learn from this tutorial?\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#part-1-your-app-an-instance-of-yourprojectapplication\"\u003ePart 1: Your app: an instance of YourProject::Application\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#part-2-config\"\u003ePart 2: config\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#part-3-every-request-and-response\"\u003ePart 3: Every request and response\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#puma\"\u003ePuma\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#rack-apps\"\u003eRack apps\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#the-core-app-actiondispatchroutingrouteset-instance\"\u003eThe core app: ActionDispatch::Routing::RouteSet instance\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#render-view\"\u003eRender view\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file\"\u003eHow can instance variables defined in Controller be accessed in view file?\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#part-4-what-does--rails-server-do\"\u003ePart 4: What does \u003ccode\u003e$ rails server\u003c/code\u003e do?\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#thor\"\u003eThor\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#railsserverstart\"\u003eRails::Server#start\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#starting-puma\"\u003eStarting Puma\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#conclusion\"\u003eConclusion\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#exiting-puma\"\u003eExiting Puma\u003c/a\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#process-and-thread\"\u003eProcess and Thread\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#send-sigterm-to-puma\"\u003eSend \u003ccode\u003eSIGTERM\u003c/code\u003e to Puma\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePart 0: Before reading Rails 5 source code\u003c/h2\u003e\u003ca id=\"user-content-part-0-before-reading-rails-5-source-code\" class=\"anchor\" aria-label=\"Permalink: Part 0: Before reading Rails 5 source code\" href=\"#part-0-before-reading-rails-5-source-code\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eI suggest you to learn Rack \u003ca href=\"http://rack.github.io/\" rel=\"nofollow\"\u003ehttp://rack.github.io/\u003c/a\u003e first.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eIn Rack, an object with \u003ccode\u003ecall\u003c/code\u003e method is a Rack app.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSo what is the object with \u003ccode\u003ecall\u003c/code\u003e method in Rails? I will answer this question in Part 1.\u003c/p\u003e\n\u003col start=\"2\" dir=\"auto\"\u003e\n\u003cli\u003eYou need a good IDE which can help for debugging. I use \u003ca href=\"https://www.jetbrains.com/\" rel=\"nofollow\"\u003eRubyMine\u003c/a\u003e.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhat will you learn from this tutorial?\u003c/h3\u003e\u003ca id=\"user-content-what-will-you-learn-from-this-tutorial\" class=\"anchor\" aria-label=\"Permalink: What will you learn from this tutorial?\" href=\"#what-will-you-learn-from-this-tutorial\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eHow does Rails start your application?\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eHow does Rails process every request?\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eHow does Rails combine ActionController, ActionView and Routes together?\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eHow does Puma, Rack, Rails work together?\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eWhat's Puma's multiple threads?\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eI should start with the command \u003ccode\u003e$ rails server\u003c/code\u003e, but I put this to Part 4. Because it's a little bit complex.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePart 1: Your app: an instance of YourProject::Application\u003c/h2\u003e\u003ca id=\"user-content-part-1-your-app-an-instance-of-yourprojectapplication\" class=\"anchor\" aria-label=\"Permalink: Part 1: Your app: an instance of YourProject::Application\" href=\"#part-1-your-app-an-instance-of-yourprojectapplication\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAssume your Rails app's class name is \u003ccode\u003eYourProject::Application\u003c/code\u003e (defined in \u003ccode\u003e./config/application.rb\u003c/code\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFirst, I will give you a piece of important code.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\nmodule Rails\n  module Command\n    class ServerCommand \u0026lt; Base\n      def perform\n        # ...\n        Rails::Server.new(server_options).tap do |server|\n          # APP_PATH is '/path/to/your_project/config/application'.\n          # require APP_PATH will create the 'Rails.application' object.\n          # Actually, 'Rails.application' is an instance of `YourProject::Application`.\n          # Rack server will start 'Rails.application'.\n          require APP_PATH\n          \n          Dir.chdir(Rails.application.root)\n          \n          server.start\n        end\n      end\n    end\n  end\n  \n  class Server \u0026lt; ::Rack::Server\n    def start\n      #...\n      # 'wrapped_app' will get an well prepared app from `./config.ru` file.\n      # 'wrapped_app' will return an instance of `YourProject::Application`.\n      # But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.\n      # It has been created when `require APP_PATH` in previous code: \n      # in Rails::Command::ServerCommand#perform\n      wrapped_app   \n\n      super # Will invoke ::Rack::Server#start. \n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServerCommand\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eperform\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eserver_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etap\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e|\n          \u003cspan class=\"pl-c\"\u003e# APP_PATH is '/path/to/your_project/config/application'.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# require APP_PATH will create the 'Rails.application' object.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Actually, 'Rails.application' is an instance of `YourProject::Application`.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Rack server will start 'Rails.application'.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eAPP_PATH\u003c/span\u003e\n          \n          \u003cspan class=\"pl-v\"\u003eDir\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003echdir\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eroot\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \n          \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estart\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e \u0026lt; ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'wrapped_app' will get an well prepared app from `./config.ru` file.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'wrapped_app' will return an instance of `YourProject::Application`.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# It has been created when `require APP_PATH` in previous code: \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# in Rails::Command::ServerCommand#perform\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003ewrapped_app\u003c/span\u003e   \n\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Will invoke ::Rack::Server#start. \u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA Rack server need to start with an \u003ccode\u003eApp\u003c/code\u003e object. The \u003ccode\u003eApp\u003c/code\u003e object should have a \u003ccode\u003ecall\u003c/code\u003e method.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003econfig.ru\u003c/code\u003e is the conventional entry file for Rack app. So let's look at it.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config.ru\nrequire_relative 'config/environment'\n\nrun Rails.application # It seems that this is the app.\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config.ru\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire_relative\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'config/environment'\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# It seems that this is the app.\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eLet's test it by \u003ccode\u003eRails.application.respond_to?(:call)\u003c/code\u003e, it returns \u003ccode\u003etrue\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet's step into \u003ccode\u003eRails.application\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties-5.2.2/lib/rails.rb\nmodule Rails\n  class \u0026lt;\u0026lt; self\n    @application = @app_class = nil\n\n    attr_accessor :app_class\n    \n    # Oh, 'application' is a class method for module 'Rails'. It is not an object.\n    # But it returns an object which is an instance of 'app_class'.\n    # So it is important for us to know what class 'app_class' is.\n    def application\n      @application ||= (app_class.instance if app_class)  \n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e@application\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@app_class\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n\n    \u003cspan class=\"pl-en\"\u003eattr_accessor\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:app_class\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Oh, 'application' is a class method for module 'Rails'. It is not an object.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# But it returns an object which is an instance of 'app_class'.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# So it is important for us to know what class 'app_class' is.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@application\u003c/span\u003e ||= \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp_class\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp_class\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e  \n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBecause \u003ccode\u003eRails.application.respond_to?(:call)\u003c/code\u003e returns \u003ccode\u003etrue\u003c/code\u003e, \u003ccode\u003eapp_class.instance\u003c/code\u003e has a \u003ccode\u003ecall\u003c/code\u003e method.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen was \u003ccode\u003eapp_class\u003c/code\u003e set?\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Rails\n  class Application \u0026lt; Engine\n    class \u0026lt;\u0026lt; self\n      def inherited(base) # This is a hooked method.\n        Rails.app_class = base # This line set the 'app_class'.\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einherited\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This is a hooked method.\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp_class\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This line set the 'app_class'.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eRails::Application\u003c/code\u003e is inherited by \u003ccode\u003eYourProject\u003c/code\u003e,\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config/application.rb\nmodule YourProject\n  # The hooked method `inherited` will be invoked here.\n  class Application \u0026lt; Rails::Application\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eYourProject\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# The hooked method `inherited` will be invoked here.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSo \u003ccode\u003eYourProject::Application\u003c/code\u003e is the \u003ccode\u003eRails.app_class\u003c/code\u003e here.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou may have a question: When does Rails execute the code in \u003ccode\u003e./config/application.rb\u003c/code\u003e?\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo answer this question, we need to look back to \u003ccode\u003econfig.ru\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config.ru\nrequire_relative 'config/environment' # Let's step into this line.\n\nrun Rails.application # It seems that this is the app.\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config.ru\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire_relative\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'config/environment'\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# It seems that this is the app.\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config/environment.rb\n# Load the Rails application.\nrequire_relative 'application' # Let's step into this line.\n\n# Initialize the Rails application.\nRails.application.initialize!\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config/environment.rb\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e# Load the Rails application.\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire_relative\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'application'\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# Initialize the Rails application.\u003c/span\u003e\n\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einitialize!\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config/application.rb\nrequire_relative 'boot'\n\nrequire 'rails/all'\n\n# Require the gems listed in Gemfile, including any gems\n# you've limited to :test, :development, or :production.\nBundler.require(*Rails.groups)\n\nmodule YourProject\n  # The hooked method `inherited` will be invoked here.\n  class Application \u0026lt; Rails::Application\n    config.load_defaults 5.2\n    config.i18n.default_locale = :zh\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire_relative\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'boot'\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'rails/all'\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# Require the gems listed in Gemfile, including any gems\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e# you've limited to :test, :development, or :production.\u003c/span\u003e\n\u003cspan class=\"pl-v\"\u003eBundler\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003egroups\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eYourProject\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# The hooked method `inherited` will be invoked here.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eload_defaults\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e5.2\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ei18n\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edefault_locale\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:zh\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBecause \u003ccode\u003eYourProject::Application\u003c/code\u003e is \u003ccode\u003eRails.app_class\u003c/code\u003e, \u003ccode\u003eapp_class.instance\u003c/code\u003e is \u003ccode\u003eYourProject::Application.instance\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBut where is the \u003ccode\u003ecall\u003c/code\u003e method?\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003ecall\u003c/code\u003e method should be a method of \u003ccode\u003eYourProject::Application.instance\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003ecall\u003c/code\u003e method processes every request. Here it is.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties/lib/rails/engine.rb\nmodule Rails\n  class Engine \u0026lt; Railtie\n    def call(env) # This method will process every request. It is invoked by Rack. So it is very important. \n      req = build_request env\n      app.call req.env # We will discuss the 'app' object later.\n    end\n  end\nend\n\n# ./gems/railties/lib/rails/application.rb\nmodule Rails\n  class Application \u0026lt; Engine\n  end\nend\n\n# ./config/application.rb\nmodule YourProject\n  class Application \u0026lt; Rails::Application\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/engine.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This method will process every request. It is invoked by Rack. So it is very important. \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_request\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# We will discuss the 'app' object later.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./config/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eYourProject\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAncestor's chain is \u003ccode\u003eYourProject::Application \u0026lt; Rails::Application \u0026lt; Rails::Engine \u0026lt; Rails::Railtie\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSo \u003ccode\u003eYourProject::Application.new.respond_to?(:call)\u003c/code\u003e returns \u003ccode\u003etrue\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBut what does \u003ccode\u003eapp_class.instance\u003c/code\u003e really do?\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003einstance\u003c/code\u003e is just a method name. What we really expects is something like \u003ccode\u003eapp_class.new\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet's look at the definition of \u003ccode\u003einstance\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties/lib/rails/application.rb\nmodule Rails\n  class Application \u0026lt; Engine\n    def instance\n      super.run_load_hooks! # This line confused me at the beginning. \n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun_load_hooks!\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This line confused me at the beginning. \u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAfter a deep research, I realized that this code is equal to:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"def instance\n  return_value = super # Keyword 'super' means call the ancestor's same name method: 'instance'.\n  return_value.run_load_hooks!\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e\n  \u003cspan class=\"pl-s1\"\u003ereturn_value\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Keyword 'super' means call the ancestor's same name method: 'instance'.\u003c/span\u003e\n  \u003cspan class=\"pl-s1\"\u003ereturn_value\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun_load_hooks!\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties/lib/rails/railtie.rb\nmodule Rails\n  class Railtie\n    def instance\n      # 'Rails::Railtie' is the top ancestor class.\n      # Now 'app_class.instance' is 'YourProject::Application.new'.\n      @instance ||= new\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/railtie.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'Rails::Railtie' is the top ancestor class.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Now 'app_class.instance' is 'YourProject::Application.new'.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@instance\u003c/span\u003e ||= \u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Rails\n  def application\n    @application ||= (app_class.instance if app_class)\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e@application\u003c/span\u003e ||= \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp_class\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp_class\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSo \u003ccode\u003eYourProject::Application.new\u003c/code\u003e is \u003ccode\u003eRails.application\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRack server will start \u003ccode\u003eRails.application\u003c/code\u003e in the end.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eRails.application\u003c/code\u003e is an important object in Rails.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAnd you'll only have one \u003ccode\u003eRails.application\u003c/code\u003e in one Puma process.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMultiple threads in a Puma process shares the \u003ccode\u003eRails.application\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePart 2: config\u003c/h2\u003e\u003ca id=\"user-content-part-2-config\" class=\"anchor\" aria-label=\"Permalink: Part 2: config\" href=\"#part-2-config\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe first time we see the \u003ccode\u003econfig\u003c/code\u003e is in \u003ccode\u003e./config/application.rb\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config/application.rb\n#...\nmodule YourProject\n  class Application \u0026lt; Rails::Application\n    # Actually, `config` is a method of `YourProject::Application`.\n    # It is defined in it's grandfather's father: `Rails::Railtie`\n    config.load_defaults 5.2  # Let's step into this line to see what is config.\n    config.i18n.default_locale = :zh\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config/application.rb\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eYourProject\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Actually, `config` is a method of `YourProject::Application`.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# It is defined in it's grandfather's father: `Rails::Railtie`\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eload_defaults\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e5.2\u003c/span\u003e  \u003cspan class=\"pl-c\"\u003e# Let's step into this line to see what is config.\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ei18n\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edefault_locale\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:zh\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Rails\n  class Railtie\n    class \u0026lt;\u0026lt; self\n      # Method `:config` is defined here.\n      # Actually, method `:config` is delegated to another object `:instance`.\n      delegate :config, to: :instance \n      \n      # Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`\n      def instance\n        # return an instance of `YourProject::Application`.\n        # Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`\n        @instance ||= new \n      end\n    end\n  end\n  \n  class Engine \u0026lt; Railtie\n  end\n  \n  class Application \u0026lt; Engine\n    class \u0026lt;\u0026lt; self\n      def instance\n        # 'super' will call `:instance` method in `Railtie`, \n        # which will return an instance of `YourProject::Application`.\n        return_value = super  \n        return_value.run_load_hooks!\n      end\n    end\n    \n    def run_load_hooks!\n      return self if @ran_load_hooks\n      @ran_load_hooks = true\n\n      # ...\n      self # `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.\n    end\n    \n    # This is the method `config`.\n    def config\n      # It is an instance of class `Rails::Application::Configuration`. \n      # Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   \n      @config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Method `:config` is defined here.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Actually, method `:config` is delegated to another object `:instance`.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003edelegate\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:config\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003eto\u003c/span\u003e: \u003cspan class=\"pl-pds\"\u003e:instance\u003c/span\u003e \n      \n      \u003cspan class=\"pl-c\"\u003e# Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# return an instance of `YourProject::Application`.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@instance\u003c/span\u003e ||= \u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'super' will call `:instance` method in `Railtie`, \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# which will return an instance of `YourProject::Application`.\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ereturn_value\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e  \n        \u003cspan class=\"pl-s1\"\u003ereturn_value\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun_load_hooks!\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun_load_hooks!\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@ran_load_hooks\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@ran_load_hooks\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# This is the method `config`.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# It is an instance of class `Rails::Application::Configuration`. \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@config\u003c/span\u003e ||= \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efind_root\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecalled_from\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn the end, \u003ccode\u003eYourProject::Application.config === Rails.application.config\u003c/code\u003e returns \u003ccode\u003etrue\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eInvoke Class's \u003ccode\u003econfig\u003c/code\u003e method become invoke the class's instance's \u003ccode\u003econfig\u003c/code\u003e method.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Rails\n  class \u0026lt;\u0026lt; self\n    def configuration\n      application.config\n    end \n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfiguration\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSo \u003ccode\u003eRails.configuration === Rails.application.config\u003c/code\u003e returns \u003ccode\u003etrue\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFYI:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Rails\n  class Application\n    class Configuration \u0026lt; ::Rails::Engine::Configuration\n    end\n  end\n  \n  class Engine\n    class Configuration \u0026lt; ::Rails::Railtie::Configuration\n      attr_accessor :middleware\n\n      def initialize(root = nil)\n        super()\n        #...\n        @middleware = Rails::Configuration::MiddlewareStackProxy.new\n      end\n    end\n  end\n  \n  class Railtie\n    class Configuration\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e \u0026lt; ::\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e \u0026lt; ::\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eattr_accessor\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:middleware\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@middleware\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eMiddlewareStackProxy\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePart 3: Every request and response\u003c/h2\u003e\u003ca id=\"user-content-part-3-every-request-and-response\" class=\"anchor\" aria-label=\"Permalink: Part 3: Every request and response\" href=\"#part-3-every-request-and-response\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eImagine we have this route for the home page.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./config/routes.rb\nRails.application.routes.draw do\n  root 'home#index' # HomeController#index\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./config/routes.rb\u003c/span\u003e\n\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edraw\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n  \u003cspan class=\"pl-en\"\u003eroot\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'home#index'\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# HomeController#index\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePuma\u003c/h3\u003e\u003ca id=\"user-content-puma\" class=\"anchor\" aria-label=\"Permalink: Puma\" href=\"#puma\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen a request is made from client, Puma will process the request in \u003ccode\u003ePuma::Server#process_client\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf you want to know how Puma enter the method \u003ccode\u003ePuma::Server#process_client\u003c/code\u003e, please read part 4 or just search 'process_client' in this document.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/puma-3.12.0/lib/puma/server.rb\nrequire 'socket'\n\nmodule Puma\n  # The HTTP Server itself. Serves out a single Rack app.\n  #\n  # This class is used by the `Puma::Single` and `Puma::Cluster` classes\n  # to generate one or more `Puma::Server` instances capable of handling requests.\n  # Each Puma process will contain one `Puma::Server` instacne.\n  #\n  # The `Puma::Server` instance pulls requests from the socket, adds them to a\n  # `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.\n  #\n  # Each `Puma::Server` will have one reactor and one thread pool.\n  class Server\n    def initialize(app, events=Events.stdio, options={})\n      # app: #\u0026lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 \n      #        @app = #\u0026lt;YourProject::Application:0x00007fcf160fb120\u0026gt;\n      #        @config = #\u0026lt;Puma::Configuration:0x00007fcf169a6c98\u0026gt;         \n      #       \u0026gt;\n      @app = app\n      #...\n    end\n    \n    # Given a connection on +client+, handle the incoming requests.\n    #\n    # This method support HTTP Keep-Alive so it may, depending on if the client\n    # indicates that it supports keep alive, wait for another request before\n    # returning.\n    #\n    def process_client(client, buffer)\n      begin\n        # ...\n        while true\n          # Let's step into this line.\n          case handle_request(client, buffer) # Will return true in this example.\n          when true\n            return unless @queue_requests\n            buffer.reset\n\n            ThreadPool.clean_thread_locals if clean_thread_locals\n\n            unless client.reset(@status == :run)\n              close_socket = false\n              client.set_timeout @persistent_timeout\n              @reactor.add client\n              return\n            end\n          end\n        end\n        # ...\n      ensure\n        buffer.reset\n        client.close if close_socket\n        #...\n      end\n    end\n    \n    # Given the request +env+ from +client+ and a partial request body\n    # in +body+, finish reading the body if there is one and invoke\n    # the Rack app. Then construct the response and write it back to\n    # +client+\n    #\n    def handle_request(req, lines)\n      env = req.env\n      # ... \n      # app: #\u0026lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 \n      #        @app = #\u0026lt;YourProject::Application:0x00007fcf160fb120\u0026gt;\n      #        @config = #\u0026lt;Puma::Configuration:0x00007fcf169a6c98\u0026gt;         \n      #       \u0026gt;\n      status, headers, res_body = @app.call(env) # Let's step into this line.\n\n      # ...\n      return keep_alive\n    end    \n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/puma-3.12.0/lib/puma/server.rb\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'socket'\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# The HTTP Server itself. Serves out a single Rack app.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# This class is used by the `Puma::Single` and `Puma::Cluster` classes\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# to generate one or more `Puma::Server` instances capable of handling requests.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Each Puma process will contain one `Puma::Server` instacne.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# The `Puma::Server` instance pulls requests from the socket, adds them to a\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Each `Puma::Server` will have one reactor and one thread pool.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eevents\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eEvents\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estdio\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# app: #\u0026lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#        @app = #\u0026lt;YourProject::Application:0x00007fcf160fb120\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#        @config = #\u0026lt;Puma::Configuration:0x00007fcf169a6c98\u0026gt;         \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#       \u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Given a connection on +client+, handle the incoming requests.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# This method support HTTP Keep-Alive so it may, depending on if the client\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# indicates that it supports keep alive, wait for another request before\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# returning.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_client\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003ecase\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_request\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Will return true in this example.\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@queue_requests\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereset\u003c/span\u003e\n\n            \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclean_thread_locals\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eclean_thread_locals\u003c/span\u003e\n\n            \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereset\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e == \u003cspan class=\"pl-pds\"\u003e:run\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n              \u003cspan class=\"pl-s1\"\u003eclose_socket\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n              \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eset_timeout\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@persistent_timeout\u003c/span\u003e\n              \u003cspan class=\"pl-c1\"\u003e@reactor\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eadd\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eensure\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereset\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclose\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eclose_socket\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Given the request +env+ from +client+ and a partial request body\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# in +body+, finish reading the body if there is one and invoke\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# the Rack app. Then construct the response and write it back to\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# +client+\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_request\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elines\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ... \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# app: #\u0026lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#        @app = #\u0026lt;YourProject::Application:0x00007fcf160fb120\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#        @config = #\u0026lt;Puma::Configuration:0x00007fcf169a6c98\u0026gt;         \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#       \u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003estatus\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres_body\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ekeep_alive\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/puma-3.12.0/lib/puma/configuration.rb\nmodule Puma\n  class Configuration\n    class ConfigMiddleware\n      def initialize(config, app)\n        @config = config\n        @app = app\n      end\n\n      def call(env)\n        env[Const::PUMA_CONFIG] = @config\n        # @app: #\u0026lt;YourProject::Application:0x00007fb4b1b4bcf8\u0026gt;\n        @app.call(env)\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/puma-3.12.0/lib/puma/configuration.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eConfiguration\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eConfigMiddleware\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@config\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eConst\u003c/span\u003e::\u003cspan class=\"pl-c1\"\u003ePUMA_CONFIG\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@config\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# @app: #\u0026lt;YourProject::Application:0x00007fb4b1b4bcf8\u0026gt;\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRack apps\u003c/h3\u003e\u003ca id=\"user-content-rack-apps\" class=\"anchor\" aria-label=\"Permalink: Rack apps\" href=\"#rack-apps\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs we see when Ruby enter \u003ccode\u003ePuma::Configuration::ConfigMiddleware#call\u003c/code\u003e, the \u003ccode\u003e@app\u003c/code\u003e is \u003ccode\u003eYourProject::Application\u003c/code\u003e instance.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt is just the \u003ccode\u003eRails.application\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRack need a \u003ccode\u003ecall\u003c/code\u003e method to process request.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRails defined this \u003ccode\u003ecall\u003c/code\u003e method in \u003ccode\u003eRails::Engine#call\u003c/code\u003e, so that \u003ccode\u003eYourProject::Application\u003c/code\u003e instance will have a \u003ccode\u003ecall\u003c/code\u003e method.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties/lib/rails/engine.rb\nmodule Rails\n  class Engine \u0026lt; Railtie\n    def call(env) # This method will process every request. It is invoked by Rack. \n      req = build_request env\n      app.call req.env # The 'app' method is blow.\n    end\n    \n    def app\n      # FYI,\n      # caller: [\n      # \u0026quot;../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in \u0026lt;module:Finisher\u0026gt;'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'\u0026quot;,\n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'\u0026quot;, \n      # \u0026quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'\u0026quot;, \n      # \u0026quot;/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `\u0026lt;top (required)\u0026gt;'\u0026quot;, \n      # \u0026quot;config.ru:2:in `require_relative'\u0026quot;, \u0026quot;config.ru:2:in `block in \u0026lt;main\u0026gt;'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'\u0026quot;, \n      # \u0026quot;config.ru:in `new'\u0026quot;, \u0026quot;config.ru:in `\u0026lt;main\u0026gt;'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'\u0026quot;, \n      # \u0026quot;../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\u0026quot;,\n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\u0026quot;,\n      # \u0026quot;../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\u0026quot;, \n      # \u0026quot;../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\u0026quot;,\n      # \u0026quot;../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\u0026quot;,\n      # \u0026quot;../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\u0026quot;, \n      # \u0026quot;../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u0026lt;top (required)\u0026gt;'\u0026quot;, \n      # \u0026quot;../path/to/your_project/bin/rails:5:in `require'\u0026quot;,\n      # \u0026quot;../path/to/your_project/bin/rails:5:in `\u0026lt;main\u0026gt;'\u0026quot;\n      # ]\n      puts \u0026quot;caller: #{caller.inspect}\u0026quot;\n      \n      # You may want to know when is the @app first time initialized.\n      # It is initialized when 'config.ru' is load by Rack server.\n      # Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.\n      # When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. \n      @app || @app_build_lock.synchronize { # '@app_build_lock = Mutex.new', so multiple threads share one '@app'.\n        @app ||= begin\n          # In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). \n          stack = default_middleware_stack # Let's step into this line\n          # 'middleware' is a 'middleware_stack'!\n          config.middleware = build_middleware.merge_into(stack)\n          # FYI, this line is the last line and the result of this line is the return value for @app.\n          config.middleware.build(endpoint) # look at this endpoint below. We will enter method `build` later.\n        end\n      }\n      \n#  @app: #\u0026lt;Rack::Sendfile:0x00007ff14d905f60 \n#          @app=#\u0026lt;ActionDispatch::Static:0x00007ff14d906168 \n#                 @app=#\u0026lt;ActionDispatch::Executor:0x00007ff14d9061b8 \n#                        ...\n#                           @app=#\u0026lt;Rack::ETag:0x00007fa1e540c4f8  \n#                                  @app=#\u0026lt;Rack::TempfileReaper:0x00007fa1e540c520 \n#                                         @app=#\u0026lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u0026gt;\n#                                 \u0026gt;\n#                         ...    \n#                        \u0026gt;\n#                             \n#                 \u0026gt;\n#         \u0026gt;\n      @app\n    end\n    \n    # Defaults to an ActionDispatch::Routing::RouteSet instance.\n    def endpoint\n      ActionDispatch::Routing::RouteSet.new_with_config(config)\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/engine.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRailtie\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This method will process every request. It is invoked by Rack. \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_request\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# The 'app' method is blow.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# FYI,\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# caller: [\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in \u0026lt;module:Finisher\u0026gt;'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `\u0026lt;top (required)\u0026gt;'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"config.ru:2:in `require_relative'\", \"config.ru:2:in `block in \u0026lt;main\u0026gt;'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"config.ru:in `new'\", \"config.ru:in `\u0026lt;main\u0026gt;'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u0026lt;top (required)\u0026gt;'\", \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../path/to/your_project/bin/rails:5:in `require'\",\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# \"../path/to/your_project/bin/rails:5:in `\u0026lt;main\u0026gt;'\"\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ]\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"caller: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecaller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einspect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# You may want to know when is the @app first time initialized.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# It is initialized when 'config.ru' is load by Rack server.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e || \u003cspan class=\"pl-c1\"\u003e@app_build_lock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# '@app_build_lock = Mutex.new', so multiple threads share one '@app'.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e ||= \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). \u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003estack\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edefault_middleware_stack\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# 'middleware' is a 'middleware_stack'!\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emiddleware\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_middleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emerge_into\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003estack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# FYI, this line is the last line and the result of this line is the return value for @app.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eendpoint\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# look at this endpoint below. We will enter method `build` later.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \n\u003cspan class=\"pl-c\"\u003e#  @app: #\u0026lt;Rack::Sendfile:0x00007ff14d905f60 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#          @app=#\u0026lt;ActionDispatch::Static:0x00007ff14d906168 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                 @app=#\u0026lt;ActionDispatch::Executor:0x00007ff14d9061b8 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                        ...\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                           @app=#\u0026lt;Rack::ETag:0x00007fa1e540c4f8  \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                  @app=#\u0026lt;Rack::TempfileReaper:0x00007fa1e540c520 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                         @app=#\u0026lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                 \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                         ...    \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                        \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                             \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                 \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#         \u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Defaults to an ActionDispatch::Routing::RouteSet instance.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eendpoint\u003c/span\u003e\n      \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRouting\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRouteSet\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew_with_config\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties/lib/rails/application...\nmodule Rails\n  class Application \u0026lt; Engine\n    def default_middleware_stack\n      default_stack = DefaultMiddlewareStack.new(self, config, paths)\n      default_stack.build_stack # Let's step into this line.\n    end\n    \n    class DefaultMiddlewareStack\n      attr_reader :config, :paths, :app\n\n      def initialize(app, config, paths)\n        @app = app\n        @config = config\n        @paths = paths\n      end\n\n      def build_stack\n        ActionDispatch::MiddlewareStack.new do |middleware|\n          if config.force_ssl\n            middleware.use ::ActionDispatch::SSL, config.ssl_options\n          end\n\n          middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header\n\n          if config.public_file_server.enabled\n            headers = config.public_file_server.headers || {}\n\n            middleware.use ::ActionDispatch::Static, paths[\u0026quot;public\u0026quot;].first, index: config.public_file_server.index_name, headers: headers\n          end\n\n          if rack_cache = load_rack_cache\n            require \u0026quot;action_dispatch/http/rack_cache\u0026quot;\n            middleware.use ::Rack::Cache, rack_cache\n          end\n\n          if config.allow_concurrency == false\n            # User has explicitly opted out of concurrent request\n            # handling: presumably their code is not threadsafe\n\n            middleware.use ::Rack::Lock\n          end\n\n          middleware.use ::ActionDispatch::Executor, app.executor\n\n          middleware.use ::Rack::Runtime\n          middleware.use ::Rack::MethodOverride unless config.api_only\n          middleware.use ::ActionDispatch::RequestId\n          middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies\n\n          middleware.use ::Rails::Rack::Logger, config.log_tags\n          middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app\n          middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format\n\n          unless config.cache_classes\n            middleware.use ::ActionDispatch::Reloader, app.reloader\n          end\n\n          middleware.use ::ActionDispatch::Callbacks\n          middleware.use ::ActionDispatch::Cookies unless config.api_only\n\n          if !config.api_only \u0026amp;\u0026amp; config.session_store\n            if config.force_ssl \u0026amp;\u0026amp; config.ssl_options.fetch(:secure_cookies, true) \u0026amp;\u0026amp; !config.session_options.key?(:secure)\n              config.session_options[:secure] = true\n            end\n            middleware.use config.session_store, config.session_options\n            middleware.use ::ActionDispatch::Flash\n          end\n\n          unless config.api_only\n            middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware\n          end\n\n          middleware.use ::Rack::Head\n          middleware.use ::Rack::ConditionalGet\n          middleware.use ::Rack::ETag, \u0026quot;no-cache\u0026quot;\n\n          middleware.use ::Rack::TempfileReaper unless config.api_only\n        end\n       end\n     end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties/lib/rails/application...\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApplication\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eEngine\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edefault_middleware_stack\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003edefault_stack\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eDefaultMiddlewareStack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003epaths\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003edefault_stack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebuild_stack\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eDefaultMiddlewareStack\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eattr_reader\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:config\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:paths\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:app\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epaths\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@config\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@paths\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epaths\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_stack\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eMiddlewareStack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e|\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eforce_ssl\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-c1\"\u003eSSL\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003essl_options\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eSendfile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaction_dispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ex_sendfile_header\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epublic_file_server\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eenabled\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epublic_file_server\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e || \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eStatic\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003epaths\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"public\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003eindex\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epublic_file_server\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eindex_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003eheaders\u003c/span\u003e: \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erack_cache\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eload_rack_cache\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"action_dispatch/http/rack_cache\"\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCache\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erack_cache\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eallow_concurrency\u003c/span\u003e == \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# User has explicitly opted out of concurrent request\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# handling: presumably their code is not threadsafe\u003c/span\u003e\n\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eLock\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eExecutor\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eexecutor\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRuntime\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eMethodOverride\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapi_only\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRequestId\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRemoteIp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaction_dispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eip_spoofing_check\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaction_dispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrusted_proxies\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eLogger\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003elog_tags\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eShowExceptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eshow_exceptions_app\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eDebugExceptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edebug_exception_response_format\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecache_classes\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eReloader\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereloader\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCallbacks\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCookies\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapi_only\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e !\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapi_only\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esession_store\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eforce_ssl\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003essl_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efetch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:secure_cookies\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u0026amp;\u0026amp; !\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esession_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ekey?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:secure\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esession_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:secure\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esession_store\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esession_options\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eFlash\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapi_only\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eContentSecurityPolicy\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eMiddleware\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eHead\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eConditionalGet\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eETag\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"no-cache\"\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eTempfileReaper\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapi_only\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n       \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n     \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb\nmodule ActionDispatch\n  class MiddlewareStack\n    def use(klass, *args, \u0026amp;block)\n      middlewares.push(build_middleware(klass, args, block))\n    end\n    \n    def build_middleware(klass, args, block)\n      Middleware.new(klass, args, block)\n    end    \n    \n    def build(app = Proc.new)\n      # See Enumerable#inject for more information.\n      return_val = middlewares.freeze.reverse.inject(app) do |a, middleware|\n        # a: app, and will be changed when iterating\n        # middleware: #\u0026lt;ActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8\u0026gt;, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating\n        middleware.build(a) # Let's step into this line.\n      end\n\n      return_val\n    end    \n    \n    class Middleware\n      def initialize(klass, args, block)\n        @klass = klass\n        @args  = args\n        @block = block\n      end\n\n      def build(app)\n        # klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.\n        # It's typical Rack app to use these middlewares.\n        # See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. \n        klass.new(app, *args, \u0026amp;block)\n      end      \n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eMiddlewareStack\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003euse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003emiddlewares\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epush\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebuild_middleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_middleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-v\"\u003eMiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eProc\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# See Enumerable#inject for more information.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ereturn_val\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emiddlewares\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efreeze\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereverse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einject\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e|\n        \u003cspan class=\"pl-c\"\u003e# a: app, and will be changed when iterating\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# middleware: #\u0026lt;ActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8\u0026gt;, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-s1\"\u003ereturn_val\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n    \n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eMiddleware\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@klass\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eklass\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@args\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@block\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# It's typical Rack app to use these middlewares.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. \u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eklass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-en\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-en\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e      \n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThe core app: ActionDispatch::Routing::RouteSet instance\u003c/h3\u003e\u003ca id=\"user-content-the-core-app-actiondispatchroutingrouteset-instance\" class=\"anchor\" aria-label=\"Permalink: The core app: ActionDispatch::Routing::RouteSet instance\" href=\"#the-core-app-actiondispatchroutingrouteset-instance\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# Paste again FYI. \n#  @app: #\u0026lt;Rack::Sendfile:0x00007ff14d905f60 \n#          @app=#\u0026lt;ActionDispatch::Static:0x00007ff14d906168 \n#                 @app=#\u0026lt;ActionDispatch::Executor:0x00007ff14d9061b8 \n#                        ...\n#                           @app=#\u0026lt;Rack::ETag:0x00007fa1e540c4f8  \n#                                  @app=#\u0026lt;Rack::TempfileReaper:0x00007fa1e540c520 \n#                                         @app=#\u0026lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u0026gt;\n#                                 \u0026gt;\n#                         ...    \n#                        \u0026gt;\n#                             \n#                 \u0026gt;\n#         \u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# Paste again FYI. \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#  @app: #\u0026lt;Rack::Sendfile:0x00007ff14d905f60 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#          @app=#\u0026lt;ActionDispatch::Static:0x00007ff14d906168 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                 @app=#\u0026lt;ActionDispatch::Executor:0x00007ff14d9061b8 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                        ...\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                           @app=#\u0026lt;Rack::ETag:0x00007fa1e540c4f8  \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                  @app=#\u0026lt;Rack::TempfileReaper:0x00007fa1e540c520 \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                         @app=#\u0026lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                                 \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                         ...    \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                        \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                             \u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#                 \u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e#         \u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs we see in the Rack middleware stack, the last @app is\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e@app=#\u0026lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u0026gt;\u003c/code\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb\nmodule ActionDispatch\n  module Routing\n    class RouteSet\n      def initialize(config = DEFAULT_CONFIG)\n        @set    = Journey::Routes.new\n        @router = Journey::Router.new(@set)\n      end\n    \n      def call(env)\n        req = make_request(env) # return ActionDispatch::Request.new(env)\n        req.path_info = Journey::Router::Utils.normalize_path(req.path_info)\n        @router.serve(req) # Let's step into this line.\n      end\n    end\n  end\n  \n# ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  \n  module Journey\n    class Router\n      class RoutingError \u0026lt; ::StandardError\n      end\n    \n      attr_accessor :routes\n        \n      def initialize(routes)\n        @routes = routes\n      end\n        \n      def serve(req)\n        find_routes(req).each do |match, parameters, route| # Let's step into 'find_routes'\n          set_params  = req.path_parameters\n          path_info   = req.path_info\n          script_name = req.script_name\n        \n          unless route.path.anchored\n            req.script_name = (script_name.to_s + match.to_s).chomp(\u0026quot;/\u0026quot;)\n            req.path_info = match.post_match\n            req.path_info = \u0026quot;/\u0026quot; + req.path_info unless req.path_info.start_with? \u0026quot;/\u0026quot;\n          end\n        \n          parameters = route.defaults.merge parameters.transform_values { |val|\n            val.dup.force_encoding(::Encoding::UTF_8)\n          }\n        \n          req.path_parameters = set_params.merge parameters\n        \n          # 'route' is an instance of ActionDispatch::Journey::Route. \n          # 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.\n          status, headers, body = route.app.serve(req) # Let's step into method 'serve'\n        \n          if \u0026quot;pass\u0026quot; == headers[\u0026quot;X-Cascade\u0026quot;]\n            req.script_name     = script_name\n            req.path_info       = path_info\n            req.path_parameters = set_params\n            next\n          end\n        \n          return [status, headers, body]\n        end\n    \n        [404, { \u0026quot;X-Cascade\u0026quot; =\u0026gt; \u0026quot;pass\u0026quot; }, [\u0026quot;Not Found\u0026quot;]]\n      end\n      \n      def find_routes(req)\n        routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|\n          r.path.match(req.path_info)\n        }\n\n        routes =\n          if req.head?\n            match_head_routes(routes, req)\n          else\n            match_routes(routes, req)\n          end\n\n        routes.sort_by!(\u0026amp;:precedence)\n\n        routes.map! { |r|\n          match_data = r.path.match(req.path_info)\n          path_parameters = {}\n          match_data.names.zip(match_data.captures) { |name, val|\n            path_parameters[name.to_sym] = Utils.unescape_uri(val) if val\n          }\n          [match_data, path_parameters, r]\n        }\n      end\n\n    end\n  end\nend\n\n# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb\nmodule ActionDispatch\n  module Routing\n    class RouteSet\n      class Dispatcher \u0026lt; Routing::Endpoint\n        def serve(req)\n          params     = req.path_parameters # params: { action: 'index', controller: 'home' }\n          controller = controller(req) # controller: HomeController\n          # The definition of 'make_response!' is \n          # ActionDispatch::Response.create.tap { |res| res.request = request; }\n          res        = controller.make_response!(req) \n          dispatch(controller, params[:action], req, res) # Let's step into this line.\n        rescue ActionController::RoutingError\n          if @raise_on_name_error\n            raise\n          else\n            return [404, { \u0026quot;X-Cascade\u0026quot; =\u0026gt; \u0026quot;pass\u0026quot; }, []]\n          end\n        end\n        \n        private\n        \n        def controller(req)\n          req.controller_class\n        rescue NameError =\u0026gt; e\n          raise ActionController::RoutingError, e.message, e.backtrace\n        end\n\n        def dispatch(controller, action, req, res)\n          controller.dispatch(action, req, res) # Let's step into this line.\n        end\n      end\n    end\n  end    \nend\n\n# ./gems/actionpack-5.2.2/lib/action_controller/metal.rb\nmodule ActionController\n  class Metal \u0026lt; AbstractController::Base\n    abstract!\n    \n    def self.controller_name\n      @controller_name ||= name.demodulize.sub(/Controller$/, \u0026quot;\u0026quot;).underscore\n    end\n\n    def self.make_response!(request)\n      ActionDispatch::Response.new.tap do |res|\n        res.request = request\n      end\n    end\n    \n    class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new\n    \n    def self.inherited(base)\n      base.middleware_stack = middleware_stack.dup\n      super\n    end\n    \n    # Direct dispatch to the controller. Instantiates the controller, then\n    # executes the action named +name+.\n    def self.dispatch(name, req, res)\n      if middleware_stack.any?\n        middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env\n      else\n        # 'self' is HomeController, so for this line Rails will new a HomeController instance.  \n        # Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.\n        # These are some typical superclasses of HomeController. \n        # HomeController\n        # \u0026lt; ApplicationController\n        # \u0026lt; ActionController::Base\n        # \u0026lt; ActiveRecord::Railties::ControllerRuntime (module included)\n        # \u0026lt; ActionController::Instrumentation (module included)\n        # \u0026lt; ActionController::Rescue (module included)\n        # \u0026lt; AbstractController::Callbacks (module included)\n        # \u0026lt; ActionController::ImplicitRender (module included)\n        # \u0026lt; ActionController::BasicImplicitRender (module included)\n        # \u0026lt; ActionController::Renderers (module included) \n        # \u0026lt; ActionController::Rendering (module included) \n        # \u0026lt; ActionView::Layouts (module included) \n        # \u0026lt; ActionView::Rendering (module included)\n        # \u0026lt; ActionDispatch::Routing::UrlFor (module included) \n        # \u0026lt; AbstractController::Rendering (module included)\n        # \u0026lt; ActionController::Metal\n        # \u0026lt; AbstractController::Base\n        new.dispatch(name, req, res) # Let's step into this line.\n      end\n    end\n    \n    def dispatch(name, request, response)\n      set_request!(request)\n      set_response!(response)\n      process(name) # Let's step into this line.\n      request.commit_flash\n      to_a\n    end\n    \n    def to_a\n      response.to_a\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb\nmodule AbstractController\n  class Base\n    def process(action, *args)\n      @_action_name = action.to_s\n\n      unless action_name = _find_action_name(@_action_name)\n        raise ActionNotFound, \u0026quot;The action '#{action}' could not be found for #{self.class.name}\u0026quot;\n      end\n\n      @_response_body = nil\n\n      # action_name: 'index'\n      process_action(action_name, *args) # Let's step into this line.\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb\nmodule ActionController\n  module Instrumentation\n    def process_action(*args)\n      raw_payload = {\n        controller: self.class.name,\n        action: action_name,\n        params: request.filtered_parameters,\n        headers: request.headers,\n        format: request.format.ref,\n        method: request.request_method,\n        path: request.fullpath\n      }\n    \n      ActiveSupport::Notifications.instrument(\u0026quot;start_processing.action_controller\u0026quot;, raw_payload.dup)\n    \n      ActiveSupport::Notifications.instrument(\u0026quot;process_action.action_controller\u0026quot;, raw_payload) do |payload|\n        begin\n          # self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;\n          result = super # Let's step into this line.\n          payload[:status] = response.status\n          result\n        ensure\n          append_info_to_payload(payload)\n        end\n      end\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb\nmodule ActionController\n  module Rescue\n    def process_action(*args)\n      super # Let's step into this line.\n    rescue Exception =\u0026gt; exception\n      request.env[\u0026quot;action_dispatch.show_detailed_exceptions\u0026quot;] ||= show_detailed_exceptions?\n      rescue_with_handler(exception) || raise\n    end\n  end  \nend\n\n# .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb\nmodule AbstractController\n  # = Abstract Controller Callbacks\n  #\n  # Abstract Controller provides hooks during the life cycle of a controller action.\n  # Callbacks allow you to trigger logic during this cycle. Available callbacks are:\n  #\n  # * \u0026lt;tt\u0026gt;after_action\u0026lt;/tt\u0026gt;\n  # * \u0026lt;tt\u0026gt;before_action\u0026lt;/tt\u0026gt;\n  # * \u0026lt;tt\u0026gt;skip_before_action\u0026lt;/tt\u0026gt;\n  # * ...\n  module Callbacks\n    def process_action(*args)\n      run_callbacks(:process_action) do\n        # self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;\n        super # Let's step into this line.\n      end\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb\nmodule ActionController\n  module Rendering\n    def process_action(*)\n      self.formats = request.formats.map(\u0026amp;:ref).compact\n      super # Let's step into this line.\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb\nmodule AbstractController\n  class Base\n    def process_action(method_name, *args)\n      # self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;, method_name: 'index'\n      # In the end, method 'send_action' is method 'send' by `alias send_action send` \n      send_action(method_name, *args)\n    end\n\n    alias send_action send\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb\nmodule ActionController\n  module BasicImplicitRender\n    def send_action(method, *args)\n      # self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;, method_name: 'index'    \n      # Because 'send_action' is an alias of 'send',  \n      # self.send('index', *args) will goto HomeController#index.\n      x = super\n      # performed?: false (for this example)\n      x.tap { default_render unless performed? } # Let's step into 'default_render' later.\n    end\n  end\nend\n\n# ./your_project/app/controllers/home_controller.rb\nclass HomeController \u0026lt; ApplicationController\n  # Will go back to BasicImplicitRender#send_action when method 'index' is done.\n  def index\n    # Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?\n    # I will answer this question later. \n    @users = User.all.pluck(:id, :name)\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRouting\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRouteSet\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eDEFAULT_CONFIG\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@set\u003c/span\u003e    \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eJourney\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRoutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@router\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eJourney\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRouter\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@set\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emake_request\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# return ActionDispatch::Request.new(env)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_info\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eJourney\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRouter\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eUtils\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enormalize_path\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_info\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@router\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eserve\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n\u003cspan class=\"pl-c\"\u003e# ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  \u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eJourney\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRouter\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRoutingError\u003c/span\u003e \u0026lt; ::\u003cspan class=\"pl-v\"\u003eStandardError\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n      \u003cspan class=\"pl-en\"\u003eattr_accessor\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:routes\u003c/span\u003e\n        \n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@routes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eserve\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003efind_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ematch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparameters\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroute\u003c/span\u003e| \u003cspan class=\"pl-c\"\u003e# Let's step into 'find_routes'\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eset_params\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_parameters\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e   \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e\n        \n          \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroute\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eanchored\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_s\u003c/span\u003e + \u003cspan class=\"pl-s1\"\u003ematch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_s\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003echomp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"/\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ematch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epost_match\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"/\"\u003c/span\u003e + \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estart_with?\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"/\"\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n          \u003cspan class=\"pl-s1\"\u003eparameters\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroute\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edefaults\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emerge\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparameters\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etransform_values\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eval\u003c/span\u003e|\n            \u003cspan class=\"pl-s1\"\u003eval\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eforce_encoding\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eEncoding\u003c/span\u003e::\u003cspan class=\"pl-c1\"\u003eUTF_8\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n        \n          \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_parameters\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eset_params\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emerge\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparameters\u003c/span\u003e\n        \n          \u003cspan class=\"pl-c\"\u003e# 'route' is an instance of ActionDispatch::Journey::Route. \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003estatus\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebody\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroute\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eserve\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into method 'serve'\u003c/span\u003e\n        \n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"pass\"\u003c/span\u003e == \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"X-Cascade\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e     \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003escript_name\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e       \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epath_info\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_parameters\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eset_params\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003enext\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n          \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003estatus\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eheaders\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebody\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n        \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e404\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"X-Cascade\"\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"pass\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"Not Found\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003efind_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003efilter_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_info\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econcat\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecustom_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efind_all\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003er\u003c/span\u003e|\n          \u003cspan class=\"pl-s1\"\u003er\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ematch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_info\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ehead?\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003ematch_head_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003ematch_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esort_by!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u0026amp;\u003cspan class=\"pl-pds\"\u003e:precedence\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emap!\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003er\u003c/span\u003e|\n          \u003cspan class=\"pl-s1\"\u003ematch_data\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003er\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ematch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_info\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003epath_parameters\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003ematch_data\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enames\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ezip\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ematch_data\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecaptures\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eval\u003c/span\u003e|\n            \u003cspan class=\"pl-s1\"\u003epath_parameters\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_sym\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eUtils\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunescape_uri\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eval\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eval\u003c/span\u003e\n          \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n          \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ematch_data\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epath_parameters\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003er\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n        \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRouting\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRouteSet\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eDispatcher\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRouting\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eEndpoint\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eserve\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eparams\u003c/span\u003e     \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epath_parameters\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# params: { action: 'index', controller: 'home' }\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# controller: HomeController\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# The definition of 'make_response!' is \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# ActionDispatch::Response.create.tap { |res| res.request = request; }\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e        \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emake_response!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \n          \u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparams\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRoutingError\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@raise_on_name_error\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e404\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"X-Cascade\"\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"pass\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n        \u003cspan class=\"pl-k\"\u003eprivate\u003c/span\u003e\n        \n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econtroller_class\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eNameError\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRoutingError\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emessage\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebacktrace\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eaction\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eaction\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/actionpack-5.2.2/lib/action_controller/metal.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eMetal\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eabstract!\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econtroller_name\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@controller_name\u003c/span\u003e ||= \u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edemodulize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esub\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-sr\"\u003e/Controller$/\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunderscore\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emake_response!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-v\"\u003eActionDispatch\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eResponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etap\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e|\n        \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-en\"\u003eclass_attribute\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:middleware_stack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003edefault\u003c/span\u003e: \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eMiddlewareStack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einherited\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emiddleware_stack\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emiddleware_stack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Direct dispatch to the controller. Instantiates the controller, then\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# executes the action named +name+.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emiddleware_stack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eany?\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003emiddleware_stack\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eenv\u003c/span\u003e| \u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eenv\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'self' is HomeController, so for this line Rails will new a HomeController instance.  \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# These are some typical superclasses of HomeController. \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# HomeController\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ApplicationController\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Base\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActiveRecord::Railties::ControllerRuntime (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Instrumentation (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Rescue (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; AbstractController::Callbacks (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::ImplicitRender (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::BasicImplicitRender (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Renderers (module included) \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Rendering (module included) \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionView::Layouts (module included) \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionView::Rendering (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionDispatch::Routing::UrlFor (module included) \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; AbstractController::Rendering (module included)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; ActionController::Metal\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# \u0026lt; AbstractController::Base\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ereq\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eres\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eset_request!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eset_response!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eresponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eprocess\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecommit_flash\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eto_a\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eto_a\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eresponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_a\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eaction\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@_action_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eaction\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_s\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eaction_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_find_action_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@_action_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionNotFound\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"The action '\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eaction\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e' could not be found for \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@_response_body\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# action_name: 'index'\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eInstrumentation\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eraw_payload\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003econtroller\u003c/span\u003e: \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003eaction\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003eparams\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efiltered_parameters\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003eheaders\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eheaders\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003eformat\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformat\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eref\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003emethod\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erequest_method\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-pds\"\u003epath\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efullpath\u003c/span\u003e\n      \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n    \n      \u003cspan class=\"pl-v\"\u003eActiveSupport\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eNotifications\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einstrument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"start_processing.action_controller\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eraw_payload\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \n      \u003cspan class=\"pl-v\"\u003eActiveSupport\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eNotifications\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einstrument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"process_action.action_controller\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eraw_payload\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003epayload\u003c/span\u003e|\n        \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003epayload\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:status\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eresponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estatus\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eensure\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eappend_info_to_payload\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epayload\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRescue\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eexception\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"action_dispatch.show_detailed_exceptions\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e ||= \u003cspan class=\"pl-en\"\u003eshow_detailed_exceptions?\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003erescue_with_handler\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eexception\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e || \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# = Abstract Controller Callbacks\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Abstract Controller provides hooks during the life cycle of a controller action.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Callbacks allow you to trigger logic during this cycle. Available callbacks are:\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# * \u0026lt;tt\u0026gt;after_action\u0026lt;/tt\u0026gt;\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# * \u0026lt;tt\u0026gt;before_action\u0026lt;/tt\u0026gt;\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# * \u0026lt;tt\u0026gt;skip_before_action\u0026lt;/tt\u0026gt;\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# * ...\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCallbacks\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003erun_callbacks\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:process_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;\u003c/span\u003e\n        \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u0026amp;\u003cspan class=\"pl-pds\"\u003e:ref\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecompact\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eprocess_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;, method_name: 'index'\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# In the end, method 'send_action' is method 'send' by `alias send_action send` \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003esend_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n    \u003cspan class=\"pl-k\"\u003ealias\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esend_action\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBasicImplicitRender\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esend_action\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emethod\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007fcd3c5dfd48\u0026gt;, method_name: 'index'    \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Because 'send_action' is an alias of 'send',  \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self.send('index', *args) will goto HomeController#index.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# performed?: false (for this example)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etap\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edefault_render\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eperformed?\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into 'default_render' later.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./your_project/app/controllers/home_controller.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eHomeController\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eApplicationController\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Will go back to BasicImplicitRender#send_action when method 'index' is done.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eindex\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# I will answer this question later. \u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e@users\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eUser\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epluck\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:id\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./app/views/home/index.html.erb\n\u0026lt;div class=\u0026quot;container\u0026quot;\u0026gt;\n  \u0026lt;h1 class=\u0026quot;display-4 font-italic\u0026quot;\u0026gt;\n    \u0026lt;%= t('home.banner_title') %\u0026gt;\n    \u0026lt;%= @users %\u0026gt;\n  \u0026lt;/h1\u0026gt;\n\u0026lt;/div\u0026gt;\"\u003e\u003cpre\u003e# ./app/views/home/index.html.erb\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003ediv\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eclass\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003econtainer\u003c/span\u003e\"\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n  \u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eh1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eclass\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003edisplay-4 font-italic\u003c/span\u003e\"\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e%= t('home.banner_title') %\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e%= @users %\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n  \u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eh1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003ediv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRender view\u003c/h3\u003e\u003ca id=\"user-content-render-view\" class=\"anchor\" aria-label=\"Permalink: Render view\" href=\"#render-view\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs we see in \u003ccode\u003eActionController::BasicImplicitRender::send_action\u003c/code\u003e, the last line is \u003ccode\u003edefault_render\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSo after \u003ccode\u003eHomeController#index\u003c/code\u003e is done, Ruby will execute method \u003ccode\u003edefault_render\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb \nmodule ActionController\n  # Handles implicit rendering for a controller action that does not\n  # explicitly respond with +render+, +respond_to+, +redirect+, or +head+.\n  module ImplicitRender\n    def default_render(*args)\n      # Let's step into template_exists?\n      if template_exists?(action_name.to_s, _prefixes, variants: request.variant)\n        # Rails has found the default template './app/views/home/index.html.erb', so render it.\n        render(*args) # Let's step into this line later\n      #...\n      else\n        logger.info \u0026quot;No template found for #{self.class.name}\\##{action_name}, rendering head :no_content\u0026quot; if logger\n        super\n      end\n    end\n  end\nend\n\n# .gems/actionview-5.2.2/lib/action_view/lookup_context.rb\nmodule ActionView\n  class LookupContext\n    module ViewPaths\n      # Rails checks whether the default template exists.\n      def exists?(name, prefixes = [], partial = false, keys = [], **options)\n        @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))\n      end\n      alias :template_exists? :exists?\n    end\n  end  \nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb\nmodule ActionController\n  module Instrumentation\n    def render(*args)\n      render_output = nil\n      self.view_runtime = cleanup_view_runtime do\n        Benchmark.ms {\n          # self: #\u0026lt;HomeController:0x00007fa7e9c54278\u0026gt; \n          render_output = super # Let's step into super \n        }\n      end\n      render_output\n    end\n  end  \nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb\nmodule ActionController\n  module Rendering\n    # Check for double render errors and set the content_type after rendering.\n    def render(*args)\n      raise ::AbstractController::DoubleRenderError if response_body\n      super # Let's step into super\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb\nmodule AbstractController\n  module Rendering\n    # Normalizes arguments, options and then delegates render_to_body and\n    # sticks the result in \u0026lt;tt\u0026gt;self.response_body\u0026lt;/tt\u0026gt;.\n    def render(*args, \u0026amp;block)\n      options = _normalize_render(*args, \u0026amp;block)\n      \n      rendered_body = render_to_body(options) # Let's step into this line.\n      \n      if options[:html]\n        _set_html_content_type\n      else\n        _set_rendered_content_type rendered_format\n      end\n      \n      self.response_body = rendered_body\n    end\n  end\nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb\nmodule ActionController\n  module Renderers\n    def render_to_body(options)\n      _render_to_body_with_renderer(options) || super # Let's step into this line and 'super' later.\n    end\n    \n    # For this example, this method return nil in the end.\n    def _render_to_body_with_renderer(options)\n      # The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`\n      # '_renderers' is an instance predicate method. For more information, \n      # see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  \n      _renderers.each do |name|\n        if options.key?(name)\n          _process_options(options)\n          method_name = Renderers._render_with_renderer_method_name(name)\n          return send(method_name, options.delete(name), options)\n        end\n      end\n      nil\n    end\n  end  \nend\n\n# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb\nmodule ActionController\n  module Rendering\n    def render_to_body(options = {})\n      super || _render_in_priorities(options) || \u0026quot; \u0026quot; # Let's step into 'super'\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb \u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Handles implicit rendering for a controller action that does not\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# explicitly respond with +render+, +respond_to+, +redirect+, or +head+.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eImplicitRender\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edefault_render\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Let's step into template_exists?\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003etemplate_exists?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_s\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_prefixes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003evariants\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003erequest\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003evariant\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Rails has found the default template './app/views/home/index.html.erb', so render it.\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line later\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elogger\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einfo\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"No template found for \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"pl-cce\"\u003e\\#\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e, rendering head :no_content\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003elogger\u003c/span\u003e\n        \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/lookup_context.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eLookupContext\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eViewPaths\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Rails checks whether the default template exists.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eexists?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eprefixes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epartial\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ekeys\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e **\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@view_paths\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eexists?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-en\"\u003eargs_for_lookup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eprefixes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epartial\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ekeys\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ealias\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:template_exists?\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:exists?\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eInstrumentation\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003erender_output\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eview_runtime\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecleanup_view_runtime\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eBenchmark\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ems\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007fa7e9c54278\u0026gt; \u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003erender_output\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into super \u003c/span\u003e\n        \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003erender_output\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Check for double render errors and set the content_type after rendering.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eDoubleRenderError\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eresponse_body\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into super\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAbstractController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Normalizes arguments, options and then delegates render_to_body and\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# sticks the result in \u0026lt;tt\u0026gt;self.response_body\u0026lt;/tt\u0026gt;.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_normalize_render\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \n      \u003cspan class=\"pl-s1\"\u003erendered_body\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_to_body\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:html\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003e_set_html_content_type\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003e_set_rendered_content_type\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erendered_format\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eresponse_body\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erendered_body\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRenderers\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_to_body\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003e_render_to_body_with_renderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e || \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line and 'super' later.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# For this example, this method return nil in the end.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_render_to_body_with_renderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# '_renderers' is an instance predicate method. For more information, \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003e_renderers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e|\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ekey?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003e_process_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emethod_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRenderers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e_render_with_renderer_method_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esend\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edelete\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionController\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_to_body\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e || \u003cspan class=\"pl-en\"\u003e_render_in_priorities\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e || \u003cspan class=\"pl-s\"\u003e\" \"\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into 'super'\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/actionview-5.2.2/lib/action_view/rendering.rb\nmodule ActionView\n  module Rendering\n    def render_to_body(options = {})\n      _process_options(options)\n      \n      _render_template(options) # Let's step into this line.\n    end\n    \n    def _render_template(options)\n      variant = options.delete(:variant)\n      assigns = options.delete(:assigns)\n      \n      context = view_context # We will step into this line later.\n        \n      context.assign assigns if assigns\n      lookup_context.rendered_format = nil if options[:formats]\n      lookup_context.variants = variant if variant\n        \n      view_renderer.render(context, options) # Let's step into this line.\n    end\n  end\nend\n\n# .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb\nmodule ActionView\n  class Renderer\n    def render(context, options)\n      if options.key?(:partial)\n        render_partial(context, options)\n      else\n        render_template(context, options) # Let's step into this line.\n      end\n    end\n    \n    # Direct access to template rendering.\n    def render_template(context, options)\n      TemplateRenderer.new(@lookup_context).render(context, options) # Let's step into this line.\n    end\n  end\nend\n\n# .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb\nmodule ActionView\n  class TemplateRenderer \u0026lt; AbstractRenderer\n    def render(context, options)\n      @view    = context\n      @details = extract_details(options)\n      template = determine_template(options)\n\n      prepend_formats(template.formats)\n\n      @lookup_context.rendered_format ||= (template.formats.first || formats.first)\n\n      render_template(template, options[:layout], options[:locals]) # Let's step into this line.\n    end\n    \n    def render_template(template, layout_name = nil, locals = nil)\n      view, locals = @view, locals || {}\n\n      render_with_layout(layout_name, locals) do |layout| # Let's step into this line\n        instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do\n          # template: #\u0026lt;ActionView::Template:0x00007f822759cbc0\u0026gt;\n          template.render(view, locals) { |*name| view._layout_for(*name) } # Let's step into this line\n        end\n      end\n    end\n    \n    def render_with_layout(path, locals)\n      layout  = path \u0026amp;\u0026amp; find_layout(path, locals.keys, [formats.first])\n      content = yield(layout)\n\n      if layout\n        view = @view\n        view.view_flow.set(:layout, content)\n        layout.render(view, locals) { |*name| view._layout_for(*name) }\n      else\n        content\n      end\n    end\n  end\nend\n\n# .gems/actionview-5.2.2/lib/action_view/template.rb\nmodule ActionView\n  class Template\n    def render(view, locals, buffer = nil, \u0026amp;block)\n      instrument_render_template do\n        # self: #\u0026lt;ActionView::Template:0x00007f89bab1efb8 \n        #           @identifier=\u0026quot;/path/to/your/project/app/views/home/index.html.erb\u0026quot; \n        #           @source=\u0026quot;\u0026lt;div class='container'\\n ...\u0026quot;\n        #        \u0026gt;\n        compile!(view)\n        # method_name: \u0026quot;_app_views_home_index_html_erb___3699380246341444633_70336654511160\u0026quot; (This method is defined in 'def compile(mod)' below)\n        # view: #\u0026lt;#\u0026lt;Class:0x00007ff10d6c9d18\u0026gt;:0x00007ff10ea050a8\u0026gt;, view is an instance of \u0026lt;a subclass of ActionView::Base\u0026gt; which has same instance variables defined in the instance of HomeController.\n        # You will get the result html after invoking 'view.send'. \n        view.send(method_name, locals, buffer, \u0026amp;block)\n      end\n    rescue =\u0026gt; e\n      handle_render_error(view, e)\n    end\n    \n    # Compile a template. This method ensures a template is compiled\n    # just once and removes the source after it is compiled.\n    def compile!(view)\n      return if @compiled\n\n      # Templates can be used concurrently in threaded environments\n      # so compilation and any instance variable modification must\n      # be synchronized\n      @compile_mutex.synchronize do\n        # Any thread holding this lock will be compiling the template needed\n        # by the threads waiting. So re-check the @compiled flag to avoid\n        # re-compilation\n        return if @compiled\n\n        if view.is_a?(ActionView::CompiledTemplates)\n          mod = ActionView::CompiledTemplates\n        else\n          mod = view.singleton_class\n        end\n\n        instrument(\u0026quot;!compile_template\u0026quot;) do\n          compile(mod) # Let's step into this line.\n        end\n\n        # Just discard the source if we have a virtual path. This\n        # means we can get the template back.\n        @source = nil if @virtual_path\n        @compiled = true\n      end\n    end\n    \n    def compile(mod)\n      encode!\n      # @handler: #\u0026lt;ActionView::Template::Handlers::ERB:0x00007ff10e1be188\u0026gt;\n      code = @handler.call(self) # Let's step into this line.\n\n      # Make sure that the resulting String to be eval'd is in the\n      # encoding of the code\n      source = \u0026lt;\u0026lt;-end_src.dup\n        def #{method_name}(local_assigns, output_buffer)\n          _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}\n        ensure\n          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer\n        end\n      end_src\n\n      # ...\n\n      #  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)\n      #              _old_virtual_path, @virtual_path = @virtual_path, \u0026quot;home/index\u0026quot;;_old_output_buffer = @output_buffer;;\n      #              @output_buffer = output_buffer || ActionView::OutputBuffer.new;\n      #              @output_buffer.safe_append='\u0026lt;div class=\u0026quot;container\u0026quot;\u0026gt;\n      #                \u0026lt;h1 class=\u0026quot;display-4 font-italic\u0026quot;\u0026gt;\n      #                  '.freeze;\n      #                   @output_buffer.append=( t('home.banner_title') );\n      #                   @output_buffer.append=( @users ); \n      #                   @output_buffer.safe_append='\n      #                \u0026lt;/h1\u0026gt;\n      #              \u0026lt;/div\u0026gt;\n      #              '.freeze;\n      #              @output_buffer.to_s\n      #            ensure\n      #              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer\n      #            end\n      mod.module_eval(source, identifier, 0) # This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'\n      # mod: ActionView::CompiledTemplates\n      ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])\n    end\n\n# .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     \n    module Handlers\n      class ERB\n        def call(template)\n          template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)\n\n          erb = template_source.gsub(ENCODING_TAG, \u0026quot;\u0026quot;)\n          encoding = $2\n\n          erb.force_encoding valid_encoding(template.source.dup, encoding)\n\n          # Always make sure we return a String in the default_internal\n          erb.encode!\n\n          self.class.erb_implementation.new(\n            erb,\n            escape: (self.class.escape_whitelist.include? template.type),\n            trim: (self.class.erb_trim_mode == \u0026quot;-\u0026quot;)\n          ).src\n        end\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/rendering.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_to_body\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003e_process_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003e_render_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_render_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003evariant\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edelete\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:variant\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eassigns\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edelete\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:assigns\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \n      \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eview_context\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# We will step into this line later.\u003c/span\u003e\n        \n      \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eassign\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eassigns\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eassigns\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erendered_format\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:formats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003evariants\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003evariant\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003evariant\u003c/span\u003e\n        \n      \u003cspan class=\"pl-en\"\u003eview_renderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRenderer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ekey?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:partial\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003erender_partial\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003erender_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Direct access to template rendering.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-v\"\u003eTemplateRenderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@lookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eTemplateRenderer\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eAbstractRenderer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@view\u003c/span\u003e    \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@details\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eextract_details\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edetermine_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n      \u003cspan class=\"pl-en\"\u003eprepend_formats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@lookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erendered_format\u003c/span\u003e ||= \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e || \u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n      \u003cspan class=\"pl-en\"\u003erender_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:layout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:locals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elayout_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@view\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e || \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n      \u003cspan class=\"pl-en\"\u003erender_with_layout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003elayout_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e| \u003cspan class=\"pl-c\"\u003e# Let's step into this line\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003einstrument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:template\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003eidentifier\u003c/span\u003e: \u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eidentifier\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003elayout\u003c/span\u003e: \u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etry\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:virtual_path\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# template: #\u0026lt;ActionView::Template:0x00007f822759cbc0\u0026gt;\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |*\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e| \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e_layout_for\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender_with_layout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epath\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003efind_layout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003epath\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ekeys\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eformats\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eyield\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@view\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eview_flow\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eset\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:layout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |*\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e| \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e_layout_for\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e*\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/template.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eTemplate\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erender\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003einstrument_render_template\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;ActionView::Template:0x00007f89bab1efb8 \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#           @identifier=\"/path/to/your/project/app/views/home/index.html.erb\" \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#           @source=\"\u0026lt;div class='container'\\n ...\"\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#        \u0026gt;\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003ecompile!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# method_name: \"_app_views_home_index_html_erb___3699380246341444633_70336654511160\" (This method is defined in 'def compile(mod)' below)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# view: #\u0026lt;#\u0026lt;Class:0x00007ff10d6c9d18\u0026gt;:0x00007ff10ea050a8\u0026gt;, view is an instance of \u0026lt;a subclass of ActionView::Base\u0026gt; which has same instance variables defined in the instance of HomeController.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# You will get the result html after invoking 'view.send'. \u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esend\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elocals\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003ehandle_render_error\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Compile a template. This method ensures a template is compiled\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# just once and removes the source after it is compiled.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecompile!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@compiled\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Templates can be used concurrently in threaded environments\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# so compilation and any instance variable modification must\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# be synchronized\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@compile_mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Any thread holding this lock will be compiling the template needed\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# by the threads waiting. So re-check the @compiled flag to avoid\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# re-compilation\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@compiled\u003c/span\u003e\n\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eis_a?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCompiledTemplates\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCompiledTemplates\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esingleton_class\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-en\"\u003einstrument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"!compile_template\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003ecompile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# Just discard the source if we have a virtual path. This\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# means we can get the template back.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@source\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@virtual_path\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@compiled\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecompile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eencode!\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# @handler: #\u0026lt;ActionView::Template::Handlers::ERB:0x00007ff10e1be188\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ecode\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@handler\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Make sure that the resulting String to be eval'd is in the\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# encoding of the code\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003esource\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u0026lt;\u0026lt;-end_src\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        def \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e(local_assigns, output_buffer)\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          _old_virtual_path, @virtual_path = @virtual_path, \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@virtual_path\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einspect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e;_old_output_buffer = @output_buffer;\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003elocals_code\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e;\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecode\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        ensure\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        end\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      end_src\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e#  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              _old_virtual_path, @virtual_path = @virtual_path, \"home/index\";_old_output_buffer = @output_buffer;;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              @output_buffer = output_buffer || ActionView::OutputBuffer.new;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              @output_buffer.safe_append='\u0026lt;div class=\"container\"\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                \u0026lt;h1 class=\"display-4 font-italic\"\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                  '.freeze;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                   @output_buffer.append=( t('home.banner_title') );\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                   @output_buffer.append=( @users ); \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                   @output_buffer.safe_append='\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#                \u0026lt;/h1\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              \u0026lt;/div\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              '.freeze;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              @output_buffer.to_s\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#            ensure\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#            end\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emodule_eval\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esource\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eidentifier\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# mod: ActionView::CompiledTemplates\u003c/span\u003e\n      \u003cspan class=\"pl-v\"\u003eObjectSpace\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edefine_finalizer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eFinalizer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emethod_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emod\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     \u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eHandlers\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eERB\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003etemplate_source\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esource\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eforce_encoding\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eEncoding\u003c/span\u003e::\u003cspan class=\"pl-c1\"\u003eASCII_8BIT\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003eerb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003etemplate_source\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003egsub\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eENCODING_TAG\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eencoding\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e $2\n\n          \u003cspan class=\"pl-s1\"\u003eerb\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eforce_encoding\u003c/span\u003e \u003cspan class=\"pl-en\"\u003evalid_encoding\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esource\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eencoding\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n          \u003cspan class=\"pl-c\"\u003e# Always make sure we return a String in the default_internal\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eerb\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eencode!\u003c/span\u003e\n\n          \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eerb_implementation\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003eerb\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n            \u003cspan class=\"pl-pds\"\u003eescape\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eescape_whitelist\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einclude?\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003etemplate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etype\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n            \u003cspan class=\"pl-pds\"\u003etrim\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eerb_trim_mode\u003c/span\u003e == \u003cspan class=\"pl-s\"\u003e\"-\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esrc\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHow can instance variables defined in Controller be accessed in view file?\u003c/h3\u003e\u003ca id=\"user-content-how-can-instance-variables-defined-in-controller-be-accessed-in-view-file\" class=\"anchor\" aria-label=\"Permalink: How can instance variables defined in Controller be accessed in view file?\" href=\"#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIt's time to answer the question before:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHow can instance variables like \u003ccode\u003e@users\u003c/code\u003e defined in \u003ccode\u003eHomeController\u003c/code\u003e be accessed in \u003ccode\u003e./app/views/home/index.html.erb\u003c/code\u003e?\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eI will answer this question by showing the source code below.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/actionview-5.2.2/lib/action_view/rendering.rb\nmodule ActionView\n  module Rendering\n    def view_context\n      # view_context_class is a subclass of ActionView::Base.\n      view_context_class.new( # Let's step into this line later.\n        view_renderer,\n        view_assigns, # This line will set the instance variables like '@users' in this example. Let's step into this line.  \n        self\n      )\n    end\n    \n    def view_assigns\n      # self: #\u0026lt;HomeController:0x00007f83ecfed310\u0026gt;\n      protected_vars = _protected_ivars\n      # instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  \n      variables      = instance_variables \n\n      variables.reject! { |s| protected_vars.include? s }\n      ret = variables.each_with_object({}) { |name, hash|\n        hash[name.slice(1, name.length)] = instance_variable_get(name)\n      }\n      \n      # ret: {\u0026quot;marked_for_same_origin_verification\u0026quot;=\u0026gt;true, \u0026quot;users\u0026quot;=\u0026gt;[[1, \u0026quot;Lane\u0026quot;], [2, \u0026quot;John\u0026quot;], [4, \u0026quot;Frank\u0026quot;]]}\n      ret\n    end\n    \n    def view_context_class\n      # Will return a subclass of ActionView::Base.\n      @_view_context_class ||= self.class.view_context_class\n    end\n    \n    # How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb\n    # FYI, the method 'append_features' will be executed automatically before method 'included' executed. \n    # https://apidock.com/ruby/v1_9_3_392/Module/append_features  \n    module ClassMethods\n      def view_context_class\n        # self: HomeController\n        @view_context_class ||= begin\n          supports_path = supports_path?\n          routes  = respond_to?(:_routes)  \u0026amp;\u0026amp; _routes\n          helpers = respond_to?(:_helpers) \u0026amp;\u0026amp; _helpers\n\n          Class.new(ActionView::Base) do\n            if routes\n              include routes.url_helpers(supports_path)\n              include routes.mounted_helpers\n            end\n\n            if helpers\n              include helpers\n            end\n          end\n        end\n      end\n    end\n  end\nend\n\n# ./gems/actionview-5.2.2/lib/action_view/base.rb\nmodule ActionView\n  class Base\n    def initialize(context = nil, assigns = {}, controller = nil, formats = nil)\n      @_config = ActiveSupport::InheritableOptions.new\n\n      if context.is_a?(ActionView::Renderer)\n        @view_renderer = context\n      else\n        lookup_context = context.is_a?(ActionView::LookupContext) ?\n          context : ActionView::LookupContext.new(context)\n        lookup_context.formats  = formats if formats\n        lookup_context.prefixes = controller._prefixes if controller\n        @view_renderer = ActionView::Renderer.new(lookup_context)\n      end\n\n      @cache_hit = {}\n      \n      assign(assigns) # Let's step into this line.\n      \n      assign_controller(controller)\n      _prepare_context\n    end\n    \n    def assign(new_assigns)\n      @_assigns = \n        new_assigns.each do |key, value|\n          # This line will set the instance variables (like '@users') in HomeController to itself.\n          instance_variable_set(\u0026quot;@#{key}\u0026quot;, value)\n        end\n    end\n  end\nend\n\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/actionview-5.2.2/lib/action_view/rendering.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRendering\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eview_context\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# view_context_class is a subclass of ActionView::Base.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eview_context_class\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line later.\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eview_renderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eview_assigns\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# This line will set the instance variables like '@users' in this example. Let's step into this line.  \u003c/span\u003e\n        \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eview_assigns\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;HomeController:0x00007f83ecfed310\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eprotected_vars\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e_protected_ivars\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003evariables\u003c/span\u003e      \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance_variables\u003c/span\u003e \n\n      \u003cspan class=\"pl-s1\"\u003evariables\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereject!\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003es\u003c/span\u003e| \u003cspan class=\"pl-s1\"\u003eprotected_vars\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einclude?\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eret\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003evariables\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach_with_object\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ehash\u003c/span\u003e|\n        \u003cspan class=\"pl-s1\"\u003ehash\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eslice\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003elength\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einstance_variable_get\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# ret: {\"marked_for_same_origin_verification\"=\u0026gt;true, \"users\"=\u0026gt;[[1, \"Lane\"], [2, \"John\"], [4, \"Frank\"]]}\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eret\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eview_context_class\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Will return a subclass of ActionView::Base.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@_view_context_class\u003c/span\u003e ||= \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eview_context_class\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# FYI, the method 'append_features' will be executed automatically before method 'included' executed. \u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# https://apidock.com/ruby/v1_9_3_392/Module/append_features  \u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eClassMethods\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eview_context_class\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# self: HomeController\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@view_context_class\u003c/span\u003e ||= \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003esupports_path\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esupports_path?\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erespond_to?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:_routes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e  \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003e_routes\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003ehelpers\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erespond_to?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:_helpers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003e_helpers\u003c/span\u003e\n\n          \u003cspan class=\"pl-v\"\u003eClass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003einclude\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eurl_helpers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esupports_path\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003einclude\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroutes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emounted_helpers\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ehelpers\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003einclude\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ehelpers\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/actionview-5.2.2/lib/action_view/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eassigns\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eformats\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@_config\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActiveSupport\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eInheritableOptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eis_a?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRenderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@view_renderer\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003elookup_context\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eis_a?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eLookupContext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e ?\n          \u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e : \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eLookupContext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtext\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003elookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eformats\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eformats\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eformats\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003elookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eprefixes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e_prefixes\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@view_renderer\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eActionView\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eRenderer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003elookup_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@cache_hit\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003eassign\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eassigns\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003eassign_controller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtroller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003e_prepare_context\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eassign\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003enew_assigns\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@_assigns\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \n        \u003cspan class=\"pl-s1\"\u003enew_assigns\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ekey\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003evalue\u003c/span\u003e|\n          \u003cspan class=\"pl-c\"\u003e# This line will set the instance variables (like '@users') in HomeController to itself.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003einstance_variable_set\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"@\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ekey\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003evalue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAfter all Rack apps called, user will get the response.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePart 4: What does \u003ccode\u003e$ rails server\u003c/code\u003e do?\u003c/h2\u003e\u003ca id=\"user-content-part-4-what-does--rails-server-do\" class=\"anchor\" aria-label=\"Permalink: Part 4: What does $ rails server do?\" href=\"#part-4-what-does--rails-server-do\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you start Rails by \u003ccode\u003e$ rails server\u003c/code\u003e. You may want to know what does this command do?\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe command \u003ccode\u003erails\u003c/code\u003e locates at \u003ccode\u003e./bin/\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#!/usr/bin/env ruby\nAPP_PATH = File.expand_path('../config/application', __dir__)\n\nrequire_relative '../config/boot'\nrequire 'rails/commands' # Let's look at this file.\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e#!/usr/bin/env ruby\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003eAPP_PATH\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eFile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eexpand_path\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e'../config/application'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003e__dir__\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003erequire_relative\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'../config/boot'\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'rails/commands'\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's look at this file.\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./railties-5.2.2/lib/rails/commands.rb\nrequire \u0026quot;rails/command\u0026quot;\n\naliases = {\n  \u0026quot;g\u0026quot;  =\u0026gt; \u0026quot;generate\u0026quot;,\n  \u0026quot;d\u0026quot;  =\u0026gt; \u0026quot;destroy\u0026quot;,\n  \u0026quot;c\u0026quot;  =\u0026gt; \u0026quot;console\u0026quot;,\n  \u0026quot;s\u0026quot;  =\u0026gt; \u0026quot;server\u0026quot;,\n  \u0026quot;db\u0026quot; =\u0026gt; \u0026quot;dbconsole\u0026quot;,\n  \u0026quot;r\u0026quot;  =\u0026gt; \u0026quot;runner\u0026quot;,\n  \u0026quot;t\u0026quot;  =\u0026gt; \u0026quot;test\u0026quot;\n}\n\ncommand = ARGV.shift\ncommand = aliases[command] || command # command is 'server'\n\nRails::Command.invoke command, ARGV # Let's step into this line.\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./railties-5.2.2/lib/rails/commands.rb\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"rails/command\"\u003c/span\u003e\n\n\u003cspan class=\"pl-s1\"\u003ealiases\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"g\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"generate\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"d\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"destroy\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"c\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"console\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"s\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"server\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"db\"\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"dbconsole\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"r\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"runner\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"t\"\u003c/span\u003e  \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"test\"\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eARGV\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eshift\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ealiases\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e || \u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# command is 'server'\u003c/span\u003e\n\n\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einvoke\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eARGV\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./railties-5.2.2/lib/rails/command.rb\nmodule Rails\n  module Command\n    class \u0026lt;\u0026lt; self\n      def invoke(full_namespace, args = [], **config)\n        # ...\n        # command_name: 'server'  \n        # After calling `find_by_namespace`, we will get this result:\n        # command: Rails::Command::ServerCommand\n        command = find_by_namespace(namespace, command_name)\n        \n        # Equals to: Rails::Command::ServerCommand.perform('server', args, config)\n        command.perform(command_name, args, config)\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./railties-5.2.2/lib/rails/command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einvoke\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003efull_namespace\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e **\u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# command_name: 'server'  \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# After calling `find_by_namespace`, we will get this result:\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# command: Rails::Command::ServerCommand\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003efind_by_namespace\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enamespace\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecommand_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \n        \u003cspan class=\"pl-c\"\u003e# Equals to: Rails::Command::ServerCommand.perform('server', args, config)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eperform\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecommand_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\nmodule Rails \n  module Command\n    # There is a class method 'perform' in the Base class.\n    class ServerCommand \u0026lt; Base\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e \n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# There is a class method 'perform' in the Base class.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServerCommand\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThor\u003c/h3\u003e\u003ca id=\"user-content-thor\" class=\"anchor\" aria-label=\"Permalink: Thor\" href=\"#thor\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThor is a toolkit for building powerful command-line interfaces.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://github.com/erikhuda/thor\"\u003ehttps://github.com/erikhuda/thor\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eInheritance relationship: \u003ccode\u003eRails::Command::ServerCommand \u0026lt; Rails::Command::Base \u0026lt; Thor\u003c/code\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties-5.2.2/lib/rails/command/base.rb\nmodule Rails\n  module Command\n    class Base \u0026lt; Thor\n      class \u0026lt;\u0026lt; self\n        # command: 'server'\n        def perform(command, args, config)\n          #...\n          dispatch(command, args.dup, nil, config) # Thor.dispatch\n        end\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/command/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# command: 'server'\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eperform\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Thor.dispatch\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/thor-0.20.3/lib/thor.rb\nclass Thor\n  class \u0026lt;\u0026lt; self\n    # meth is 'server'\n    def dispatch(meth, given_args, given_opts, config)\n      # ...\n      # Will new a Rails::Command::ServerCommand instance here \n      # because 'self' is Rails::Command::ServerCommand.\n      instance = new(args, opts, config)\n      # ...\n      # Method 'invoke_command' is defined in Thor::Invocation. \n      # command: {Thor::Command}#\u0026lt;struct Thor::Command name=\u0026quot;server\u0026quot; ...\u0026gt; \n      instance.invoke_command(command, trailing || [])\n    end\n  end\nend\n\n# ./gems/thor-0.20.3/lib/thor/invocation.rb\nclass Thor\n  # FYI, this module is included in Thor.\n  # And Thor is grandfather of Rails::Command::ServerCommand\n  module Invocation\n    def invoke_command(command, *args) # 'invoke_command' is defined at here.\n      # ...\n      # self: #\u0026lt;Rails::Command::ServerCommand:0x00007fdcc49791b0\u0026gt; \n      # command: {Thor::Command}#\u0026lt;struct Thor::Command name=\u0026quot;server\u0026quot; ...\u0026gt; \n      command.run(self, *args)\n    end\n  end\nend\n\n# ./gems/thor-0.20.3/lib/thor/command.rb\nclass Thor\n  class Command \u0026lt; Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)\n    def run(instance, args = [])\n      # ...\n      # instance: #\u0026lt;Rails::Command::ServerCommand:0x00007fdcc49791b0\u0026gt;\n      # name: \u0026quot;server\u0026quot;\n      # This line will invoke Rails::Command::ServerCommand#server, \n      # the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.\n      # I will show you how the instance method 'server' is implicitly defined. \n      instance.__send__(name, *args) \n    end  \n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# meth is 'server'\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003edispatch\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003egiven_args\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003egiven_opts\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Will new a Rails::Command::ServerCommand instance here \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# because 'self' is Rails::Command::ServerCommand.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eopts\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Method 'invoke_command' is defined in Thor::Invocation. \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# command: {Thor::Command}#\u0026lt;struct Thor::Command name=\"server\" ...\u0026gt; \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einvoke_command\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003etrailing\u003c/span\u003e || \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor/invocation.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# FYI, this module is included in Thor.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# And Thor is grandfather of Rails::Command::ServerCommand\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eInvocation\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einvoke_command\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# 'invoke_command' is defined at here.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self: #\u0026lt;Rails::Command::ServerCommand:0x00007fdcc49791b0\u0026gt; \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# command: {Thor::Command}#\u0026lt;struct Thor::Command name=\"server\" ...\u0026gt; \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ecommand\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor/command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eStruct\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:description\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:long_description\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:usage\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:ancestor_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# instance: #\u0026lt;Rails::Command::ServerCommand:0x00007fdcc49791b0\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# name: \"server\"\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# This line will invoke Rails::Command::ServerCommand#server, \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# I will show you how the instance method 'server' is implicitly defined. \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e__send__\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/thor-0.20.3/lib/thor.rb\nclass Thor\n  # ...\n  include Thor::Base # Will invoke hooked method 'Thor::Base.included(self)'\nend\n\n# ./gems/thor-0.20.3/lib/thor/base.rb\nmodule Thor\n  module Base\n    class \u0026lt;\u0026lt; self\n      # 'included' is a hooked method.\n      # When module 'Thor::Base' is included, method 'included' is executed. \n      def included(base) \n        # base: Thor\n        # this line will define `Thor.method_added`.  \n        base.extend ClassMethods\n        # Module 'Invocation' is included for class 'Thor' here. \n        # Because Thor is grandfather of Rails::Command::ServerCommand,\n        # 'invoke_command' will be instance method of Rails::Command::ServerCommand       \n        base.send :include, Invocation # 'invoke_command' is defined in module Invocation\n        base.send :include, Shell\n      end\n    end\n    \n    module ClassMethods\n      # 'method_added' is a hooked method.\n      # When an instance method is created in Rails::Command::ServerCommand, \n      # `method_added` will be executed.\n      # So, when method `perform` is defined in Rails::Command::ServerCommand,\n      # `method_added` will be executed and create_command('perform') will be invoked. \n      # So in the end, method 'server' will be created by alias_method('server', 'perform').\n      # And the method 'server' is for the 'server' in command `$ rails server`.\n      def method_added(meth)\n        # ...\n        # self: {Class} Rails::Command::ServerCommand \n        create_command(meth) # meth is 'perform'. Let's step into this line.\n      end\n    end\n  end\nend\n\n# ./gems/railties-5.2.2/lib/rails/command/base.rb\nmodule Rails\n  module Command\n    # Rails::Command::Base is superclass of Rails::Command::ServerCommand\n    module Base\n      class \u0026lt;\u0026lt; self\n        def create_command(meth)\n          if meth == \u0026quot;perform\u0026quot;\n            # Calling instance method 'server' of Rails::Command::ServerCommand \n            # will be transferred to call instance method 'perform'.\n            alias_method('server', meth) \n          end\n        end  \n      end\n    end\n  end\nend\n\n# ./gems/thor-0.20.3/lib/thor/command.rb\nclass Thor\n  class Command \u0026lt; Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)\n    def run(instance, args = [])\n      #...\n      # instance: {Rails::Command::ServerCommand}#\u0026lt;Rails::Command::ServerCommand:0x00007fa5f319bf40\u0026gt;\n      # name: 'server'.\n      # Will actually invoke 'instance.perform(*args)'. \n      # Equals to invoke Rails::Command::ServerCommand#perform(*args).\n      # Let's step into  Rails::Command::ServerCommand#perform.\n      instance.__send__(name, *args) \n    end\n  end\nend\n\n# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\nmodule Rails\n  module Command\n    class ServerCommand \u0026lt; Base\n      # This is the method will be executed when `$ rails server`.\n      def perform\n        # ...\n        Rails::Server.new(server_options).tap do |server|\n          # APP_PATH is '/path/to/your_project/config/application'.\n          # require APP_PATH will create the 'Rails.application' object.\n          # 'Rails.application' is 'YourProject::Application.new'.\n          # Rack server will start 'Rails.application'.\n          require APP_PATH\n          \n          Dir.chdir(Rails.application.root)\n          \n          server.start # Let's step into this line.\n        end\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n  \u003cspan class=\"pl-en\"\u003einclude\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Will invoke hooked method 'Thor::Base.included(self)'\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'included' is a hooked method.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# When module 'Thor::Base' is included, method 'included' is executed. \u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eincluded\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \n        \u003cspan class=\"pl-c\"\u003e# base: Thor\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# this line will define `Thor.method_added`.  \u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eextend\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eClassMethods\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Module 'Invocation' is included for class 'Thor' here. \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Because Thor is grandfather of Rails::Command::ServerCommand,\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'invoke_command' will be instance method of Rails::Command::ServerCommand       \u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esend\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:include\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eInvocation\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# 'invoke_command' is defined in module Invocation\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ebase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esend\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:include\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eShell\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eClassMethods\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'method_added' is a hooked method.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# When an instance method is created in Rails::Command::ServerCommand, \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# `method_added` will be executed.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# So, when method `perform` is defined in Rails::Command::ServerCommand,\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# `method_added` will be executed and create_command('perform') will be invoked. \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# So in the end, method 'server' will be created by alias_method('server', 'perform').\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# And the method 'server' is for the 'server' in command `$ rails server`.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emethod_added\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# self: {Class} Rails::Command::ServerCommand \u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003ecreate_command\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# meth is 'perform'. Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/command/base.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Rails::Command::Base is superclass of Rails::Command::ServerCommand\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ecreate_command\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e == \u003cspan class=\"pl-s\"\u003e\"perform\"\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# Calling instance method 'server' of Rails::Command::ServerCommand \u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# will be transferred to call instance method 'perform'.\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003ealias_method\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e'server'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emeth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/thor-0.20.3/lib/thor/command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThor\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eStruct\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:description\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:long_description\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:usage\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:ancestor_name\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# instance: {Rails::Command::ServerCommand}#\u0026lt;Rails::Command::ServerCommand:0x00007fa5f319bf40\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# name: 'server'.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Will actually invoke 'instance.perform(*args)'. \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Equals to invoke Rails::Command::ServerCommand#perform(*args).\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Let's step into  Rails::Command::ServerCommand#perform.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003einstance\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e__send__\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eargs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCommand\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServerCommand\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eBase\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# This is the method will be executed when `$ rails server`.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eperform\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eserver_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etap\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e|\n          \u003cspan class=\"pl-c\"\u003e# APP_PATH is '/path/to/your_project/config/application'.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# require APP_PATH will create the 'Rails.application' object.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# 'Rails.application' is 'YourProject::Application.new'.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Rack server will start 'Rails.application'.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003erequire\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eAPP_PATH\u003c/span\u003e\n          \n          \u003cspan class=\"pl-v\"\u003eDir\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003echdir\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapplication\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eroot\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \n          \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estart\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRails::Server#start\u003c/h3\u003e\u003ca id=\"user-content-railsserverstart\" class=\"anchor\" aria-label=\"Permalink: Rails::Server#start\" href=\"#railsserverstart\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\nmodule Rails\n  class Server \u0026lt; ::Rack::Server\n    def start\n      print_boot_information\n      \n      trap(:INT) do\n        exit\n      end\n      \n      create_tmp_directories\n      setup_dev_caching\n      \n      # This line is important. Although the method name seems not.\n      log_to_stdout# Let step into this line.\n\n      super # Will invoke ::Rack::Server#start. I will show you later. \n    ensure\n      puts \u0026quot;Exiting\u0026quot; unless @options \u0026amp;\u0026amp; options[:daemonize]\n    end\n    \n    def log_to_stdout\n      # 'wrapped_app' will get an well prepared Rack app from './config.ru' file.\n      # It's the first time invoke 'wrapped_app'.\n      # The app is an instance of YourProject::Application.\n      # But the app is not created in 'wrapped_app'.\n      # It has been created when `require APP_PATH` in previous code,\n      # just at the 'perform' method in Rails::Command::ServerCommand.   \n      wrapped_app # Let's step into this line\n\n      # ...\n    end\n  end\nend\n\n# ./gems/rack-2.0.6/lib/rack/server.rb\nmodule Rack\n  class Server\n    def wrapped_app\n      @wrapped_app ||= \n        build_app(\n          app # Let's step into this line.\n        )\n    end\n    \n    def app\n      @app ||= build_app_and_options_from_config # Let's step into this line.\n      @app\n    end\n    \n    def build_app_and_options_from_config\n      # ...\n      # self.options[:config]: 'config.ru'. Let's step into this line.\n      app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)\n      # ...\n      app\n    end\n    \n    # This method is called in Rails::Server#start\n    def start(\u0026amp;blk)\n      #...\n      wrapped_app\n      #...\n\n      # server: {Module} Rack::Handler::Puma\n      # wrapped_app: {YourProject::Application} #\u0026lt;YourProject::Application:0x00007f7fe5523f98\u0026gt;\n      server.run(wrapped_app, options, \u0026amp;blk) # We will step into this line (Rack::Handler::Puma.run) later.\n    end\n  end\nend\n\n# ./gems/rack/lib/rack/builder.rb\nmodule Rack\n  module Builder\n    def self.parse_file(config, opts = Server::Options.new)\n      # config: 'config.ru'\n      cfgfile = ::File.read(config)\n      \n      app = new_from_string(cfgfile, config)\n      \n      return app, options\n    end\n  \n    # Let's guess what does 'run Rails.application' do in config.ru?\n    # You may guess that: \n    #   Run YourProject::Application instance.\n    # But 'run' maybe not what you are thinking about.\n    # Because the 'self' object in 'config.ru' is #\u0026lt;Rack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]\u0026gt;, \n    # 'run' is an instance method of Rack::Builder.\n    # Let's look at the definition of the 'run' method: \n    # def run(app)\n    #   @run = app # Just set an instance variable for Rack::Builder instance.\n    # end\n    def self.new_from_string(builder_script, file=\u0026quot;(rackup)\u0026quot;)\n      # Rack::Builder implements a small DSL to iteratively construct Rack applications.\n      eval \u0026quot;Rack::Builder.new {\\n\u0026quot; + builder_script + \u0026quot;\\n}.to_app\u0026quot;,\n        TOPLEVEL_BINDING, file, 0\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRails\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e \u0026lt; ::\u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eprint_boot_information\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:INT\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eexit\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003ecreate_tmp_directories\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003esetup_dev_caching\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# This line is important. Although the method name seems not.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elog_to_stdout\u003c/span\u003e\u003cspan class=\"pl-c\"\u003e# Let step into this line.\u003c/span\u003e\n\n      \u003cspan class=\"pl-smi\"\u003esuper\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Will invoke ::Rack::Server#start. I will show you later. \u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eensure\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Exiting\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@options\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-en\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:daemonize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003elog_to_stdout\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'wrapped_app' will get an well prepared Rack app from './config.ru' file.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# It's the first time invoke 'wrapped_app'.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# The app is an instance of YourProject::Application.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# But the app is not created in 'wrapped_app'.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# It has been created when `require APP_PATH` in previous code,\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# just at the 'perform' method in Rails::Command::ServerCommand.   \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003ewrapped_app\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/rack-2.0.6/lib/rack/server.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ewrapped_app\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@wrapped_app\u003c/span\u003e ||= \n        \u003cspan class=\"pl-en\"\u003ebuild_app\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e ||= \u003cspan class=\"pl-en\"\u003ebuild_app_and_options_from_config\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ebuild_app_and_options_from_config\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# self.options[:config]: 'config.ru'. Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eBuilder\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eparse_file\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:config\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eopt_parser\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# This method is called in Rails::Server#start\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u0026amp;\u003cspan class=\"pl-s1\"\u003eblk\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003ewrapped_app\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# server: {Module} Rack::Handler::Puma\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# wrapped_app: {YourProject::Application} #\u0026lt;YourProject::Application:0x00007f7fe5523f98\u0026gt;\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewrapped_app\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblk\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# We will step into this line (Rack::Handler::Puma.run) later.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# ./gems/rack/lib/rack/builder.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eBuilder\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eparse_file\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eopts\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eOptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# config: 'config.ru'\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ecfgfile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003eFile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \n      \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003enew_from_string\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ecfgfile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eoptions\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \n    \u003cspan class=\"pl-c\"\u003e# Let's guess what does 'run Rails.application' do in config.ru?\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# You may guess that: \u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#   Run YourProject::Application instance.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# But 'run' maybe not what you are thinking about.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Because the 'self' object in 'config.ru' is #\u0026lt;Rack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]\u0026gt;, \u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# 'run' is an instance method of Rack::Builder.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Let's look at the definition of the 'run' method: \u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# def run(app)\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#   @run = app # Just set an instance variable for Rack::Builder instance.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# end\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew_from_string\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebuilder_script\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003efile\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"(rackup)\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Rack::Builder implements a small DSL to iteratively construct Rack applications.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eeval\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Rack::Builder.new {\u003cspan class=\"pl-cce\"\u003e\\n\u003c/span\u003e\"\u003c/span\u003e + \u003cspan class=\"pl-s1\"\u003ebuilder_script\u003c/span\u003e + \u003cspan class=\"pl-s\"\u003e\"\u003cspan class=\"pl-cce\"\u003e\\n\u003c/span\u003e}.to_app\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003eTOPLEVEL_BINDING\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003efile\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStarting Puma\u003c/h3\u003e\u003ca id=\"user-content-starting-puma\" class=\"anchor\" aria-label=\"Permalink: Starting Puma\" href=\"#starting-puma\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs we see in \u003ccode\u003eRack::Server#start\u003c/code\u003e, there is \u003ccode\u003eRack::Handler::Puma.run(wrapped_app, options, \u0026amp;blk)\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./gems/puma-3.12.0/lib/rack/handler/puma.rb\nmodule Rack\n  module Handler\n    module Puma\n      # This method is invoked in `Rack::Server#start`:\n      # Rack::Handler::Puma.run(wrapped_app, options, \u0026amp;blk) \n      def self.run(app, options = {})\n        conf   = self.config(app, options)\n\n        # ...\n        launcher = ::Puma::Launcher.new(conf, :events =\u0026gt; events)\n\n        begin\n          # Puma will run your app (instance of YourProject::Application)\n          launcher.run # Let's step into this line.\n        rescue Interrupt \n          puts \u0026quot;* Gracefully stopping, waiting for requests to finish\u0026quot;\n          launcher.stop\n          puts \u0026quot;* Goodbye!\u0026quot;\n        end\n      end\n    end  \n  end\nend\n\n# .gems/puma-3.12.0/lib/puma/launcher.rb\nmodule Puma\n  # Puma::Launcher is the single entry point for starting a Puma server based on user\n  # configuration. It is responsible for taking user supplied arguments and resolving them\n  # with configuration in `config/puma.rb` or `config/puma/\u0026lt;env\u0026gt;.rb`.\n  #\n  # It is responsible for either launching a cluster of Puma workers or a single\n  # Puma server.\n  class Launcher\n    def initialize(conf, launcher_args={})\n      @runner        = nil\n      @config        = conf\n\n      # ...\n      if clustered?\n        # ...\n        @runner = Cluster.new(self, @events)\n      else\n        # For this example, it is Single.new.\n        @runner = Single.new(self, @events)\n      end\n      \n      # ...\n    end\n        \n    def run\n      #...\n\n      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. \n      setup_signals # We will discuss this line later.\n      \n      set_process_title\n      \n      @runner.run # We will enter `Single.new(self, @events).run` here.\n\n      case @status\n      when :halt\n        log \u0026quot;* Stopping immediately!\u0026quot;\n      when :run, :stop\n        graceful_stop\n      when :restart\n        log \u0026quot;* Restarting...\u0026quot;\n        ENV.replace(previous_env)\n        @runner.before_restart\n        restart!\n      when :exit\n        # nothing\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./gems/puma-3.12.0/lib/rack/handler/puma.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRack\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eHandler\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# This method is invoked in `Rack::Server#start`:\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Rack::Handler::Puma.run(wrapped_app, options, \u0026amp;blk) \u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003econf\u003c/span\u003e   \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003elauncher\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e ::\u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eLauncher\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econf\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:events\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eevents\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n        \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Puma will run your app (instance of YourProject::Application)\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003elauncher\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eInterrupt\u003c/span\u003e \n          \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"* Gracefully stopping, waiting for requests to finish\"\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003elauncher\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"* Goodbye!\"\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/launcher.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Puma::Launcher is the single entry point for starting a Puma server based on user\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# configuration. It is responsible for taking user supplied arguments and resolving them\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# with configuration in `config/puma.rb` or `config/puma/\u0026lt;env\u0026gt;.rb`.\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# It is responsible for either launching a cluster of Puma workers or a single\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Puma server.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eLauncher\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econf\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elauncher_args\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e        \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@config\u003c/span\u003e        \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econf\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eclustered?\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eCluster\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@events\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# For this example, it is Single.new.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSingle\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@events\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003esetup_signals\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# We will discuss this line later.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003eset_process_title\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# We will enter `Single.new(self, @events).run` here.\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ecase\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:halt\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"* Stopping immediately!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:run\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:stop\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003egraceful_stop\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:restart\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"* Restarting...\"\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003eENV\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ereplace\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eprevious_env\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebefore_restart\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003erestart!\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:exit\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# nothing\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/single.rb\nmodule Puma\n  # This class is instantiated by the `Puma::Launcher` and used\n  # to boot and serve a Ruby application when no puma \u0026quot;workers\u0026quot; are needed\n  # i.e. only using \u0026quot;threaded\u0026quot; mode. For example `$ puma -t 1:5`\n  #\n  # At the core of this class is running an instance of `Puma::Server` which\n  # gets created via the `start_server` method from the `Puma::Runner` class\n  # that this inherits from.\n  class Single \u0026lt; Runner\n    def run\n      # ...\n\n      # @server: Puma::Server.new(app, @launcher.events, @options)\n      @server = server = start_server # Let's step into this line.\n\n      # ...\n      thread = server.run # Let's step into this line later.\n      \n      # This line will suspend the main thread execution.\n      # And the `thread`'s block (which is method `handle_servers`) will be executed.\n      # See `Thread#join` for more information.\n      # I will show you a simple example for using `thread.join`.\n      # Please search `test_thread_join.rb` in this document.\n      thread.join\n      \n      # The below line will never be executed because `thread` is always running and `thread` has joined.\n      # When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed\n      # because the block of `Signal.trap \u0026quot;SIGTERM\u0026quot;` in `Puma::Launcher#setup_signals` will be executed.\n      # If you remove the line `thread.join`, the below line will be executed, \n      # but the main thread will exit after all code executed and all the threads not joined will be killed.\n      puts \u0026quot;anything which will never be executed...\u0026quot;\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/single.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# This class is instantiated by the `Puma::Launcher` and used\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# to boot and serve a Ruby application when no puma \"workers\" are needed\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# i.e. only using \"threaded\" mode. For example `$ puma -t 1:5`\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# At the core of this class is running an instance of `Puma::Server` which\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# gets created via the `start_server` method from the `Puma::Runner` class\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# that this inherits from.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSingle\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRunner\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# @server: Puma::Server.new(app, @launcher.events, @options)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@server\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart_server\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line later.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# This line will suspend the main thread execution.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# And the `thread`'s block (which is method `handle_servers`) will be executed.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# See `Thread#join` for more information.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# I will show you a simple example for using `thread.join`.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Please search `test_thread_join.rb` in this document.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejoin\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# The below line will never be executed because `thread` is always running and `thread` has joined.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# because the block of `Signal.trap \"SIGTERM\"` in `Puma::Launcher#setup_signals` will be executed.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# If you remove the line `thread.join`, the below line will be executed, \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# but the main thread will exit after all code executed and all the threads not joined will be killed.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"anything which will never be executed...\"\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/runner.rb\nmodule Puma\n  # Generic class that is used by `Puma::Cluster` and `Puma::Single` to\n  # serve requests. This class spawns a new instance of `Puma::Server` via\n  # a call to `start_server`.\n  class Runner\n    def app\n      @app ||= @launcher.config.app\n    end\n    \n    def start_server\n      min_t = @options[:min_threads]\n      max_t = @options[:max_threads]\n\n      server = Puma::Server.new(app, @launcher.events, @options)\n      server.min_threads = min_t\n      server.max_threads = max_t\n      # ...\n\n      server\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/runner.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Generic class that is used by `Puma::Cluster` and `Puma::Single` to\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# serve requests. This class spawns a new instance of `Puma::Server` via\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# a call to `start_server`.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eRunner\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@app\u003c/span\u003e ||= \u003cspan class=\"pl-c1\"\u003e@launcher\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003econfig\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart_server\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003emin_t\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:min_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003emax_t\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:max_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n\n      \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@launcher\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eevents\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emin_threads\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emin_t\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emax_threads\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emax_t\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n\n      \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/server.rb\nmodule Puma\n  class Server\n    def run(background=true)\n      #...\n      @status = :run\n      queue_requests = @queue_requests\n\n      # This part is important.\n      # Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.\n      # And the block will process the request by calling method `process_client`.\n      # Let's step into this line later to see how Puma call the block.\n      @thread_pool = ThreadPool.new(@min_threads,\n                                    @max_threads,\n                                    IOBuffer) do |client, buffer|\n\n        # Advertise this server into the thread\n        Thread.current[ThreadLocalKey] = self\n\n        process_now = false\n\n        if queue_requests\n          process_now = client.eagerly_finish\n        end  \n        \n        # ...\n        if process_now\n          # Process the request. You can look upon `client` as request.\n          # If you want to know more about 'process_client', please read part 3 \n          # or search 'process_client' in this document.  \n          process_client(client, buffer)  \n        else\n          client.set_timeout @first_data_timeout\n          @reactor.add client\n        end\n      end\n      \n      # ...\n\n      if background # background: true (for this example)\n        # This part is important.\n        # Remember Puma created a thread here!\n        # We will know that the newly created thread's job is waiting for requests.\n        # When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.\n        # The method `handle_servers` in thread's block will be executed immediately \n        # (executed in the newly created thread, not in the main thread).\n        @thread = Thread.new { handle_servers } # Let's step into this line to see what I said.\n        return @thread\n      else\n        handle_servers\n      end\n    end\n    \n    def handle_servers      \n      sockets = [check] + @binder.ios\n      pool = @thread_pool\n      queue_requests = @queue_requests\n\n      # ...\n      \n      # The thread is always running, because @status has been set to :run in Puma::Server#run.\n      # Yes, it should always be running to transfer the incoming requests.\n      while @status == :run\n        begin\n          # This line will cause current thread waiting until a request arrives.\n          # So it will be the entry of every request!\n          # sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;] \n          ios = IO.select sockets\n        \n          ios.first.each do |sock|\n            if sock == check\n              break if handle_check\n            else\n              if io = sock.accept_nonblock\n                # You can simply look upon a Puma::Client instance as a request.  \n                client = Client.new(io, @binder.env(sock))\n                \n                # ...\n                \n                # FYI, the method '\u0026lt;\u0026lt;' is redefined.\n                # Add the request (client) to thread pool means \n                # a thread in the pool will process this request (client).   \n                pool \u0026lt;\u0026lt; client # Let's step into this line.\n                \n                pool.wait_until_not_full # Let's step into this line later.\n              end\n            end\n          end\n        rescue Object =\u0026gt; e\n          @events.unknown_error self, e, \u0026quot;Listen loop\u0026quot;\n        end\n      end\n    end    \n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/server.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebackground\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:run\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003equeue_requests\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@queue_requests\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# This part is important.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# And the block will process the request by calling method `process_client`.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Let's step into this line later to see how Puma call the block.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@min_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n                                    \u003cspan class=\"pl-c1\"\u003e@max_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n                                    \u003cspan class=\"pl-v\"\u003eIOBuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e|\n\n        \u003cspan class=\"pl-c\"\u003e# Advertise this server into the thread\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThreadLocalKey\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003eprocess_now\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003equeue_requests\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eprocess_now\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeagerly_finish\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e  \n        \n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eprocess_now\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# Process the request. You can look upon `client` as request.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# If you want to know more about 'process_client', please read part 3 \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# or search 'process_client' in this document.  \u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eprocess_client\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e  \n        \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eset_timeout\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@first_data_timeout\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@reactor\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eadd\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebackground\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# background: true (for this example)\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# This part is important.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Remember Puma created a thread here!\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# We will know that the newly created thread's job is waiting for requests.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# The method `handle_servers` in thread's block will be executed immediately \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# (executed in the newly created thread, not in the main thread).\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_servers\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line to see what I said.\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003ehandle_servers\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_servers\u003c/span\u003e      \n      \u003cspan class=\"pl-s1\"\u003esockets\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-en\"\u003echeck\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e + \u003cspan class=\"pl-c1\"\u003e@binder\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eios\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003equeue_requests\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@queue_requests\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# The thread is always running, because @status has been set to :run in Puma::Server#run.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Yes, it should always be running to transfer the incoming requests.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e == \u003cspan class=\"pl-pds\"\u003e:run\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# This line will cause current thread waiting until a request arrives.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# So it will be the entry of every request!\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;] \u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eios\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eIO\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esockets\u003c/span\u003e\n        \n          \u003cspan class=\"pl-s1\"\u003eios\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e|\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e == \u003cspan class=\"pl-en\"\u003echeck\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_check\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eio\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaccept_nonblock\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e# You can simply look upon a Puma::Client instance as a request.  \u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eClient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eio\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@binder\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n                \n                \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n                \n                \u003cspan class=\"pl-c\"\u003e# FYI, the method '\u0026lt;\u0026lt;' is redefined.\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e# Add the request (client) to thread pool means \u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e# a thread in the pool will process this request (client).   \u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n                \n                \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewait_until_not_full\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line later.\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eObject\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@events\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunknown_error\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Listen loop\"\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/thread_pool.rb\nmodule Puma\n  class ThreadPool\n    # Maintain a minimum of +min+ and maximum of +max+ threads\n    # in the pool.\n    #\n    # The block passed is the work that will be performed in each\n    # thread.\n    #\n    def initialize(min, max, *extra, \u0026amp;block)\n      #..\n      @mutex = Mutex.new\n      @todo = [] # @todo is requests (in Puma, they are Puma::Client instances) which need to be processed.  \n      @spawned = 0 # the count of @spawned threads\n      @min = Integer(min) # @min threads count\n      @max = Integer(max) # @max threads count\n      @block = block # block will be called in method `spawn_thread` to processed a request.    \n      @workers = []\n      @reaper = nil\n\n      @mutex.synchronize do\n        @min.times { spawn_thread } # Puma spawns @min count threads.\n      end\n    end\n    \n    def spawn_thread\n      @spawned += 1\n\n      # Create a new Thread now.\n      # The block of the thread will be executed immediately and separately from the calling thread (main thread).\n      th = Thread.new(@spawned) do |spawned|\n        # Thread name is new in Ruby 2.3\n        Thread.current.name = 'puma %03i' % spawned if Thread.current.respond_to?(:name=)\n        block = @block\n        mutex = @mutex\n        #...\n\n        extra = @extra.map { |i| i.new }\n\n        # Pay attention to here: \n        # 'while true' means this part will always be running.\n        # And there will be @min count threads always running!\n        # Puma uses these threads to process requests. \n        # The line: 'not_empty.wait(mutex)' will make current thread waiting.  \n        while true\n          work = nil\n\n          continue = true\n\n          mutex.synchronize do\n            while todo.empty?\n              if @trim_requested \u0026gt; 0\n                @trim_requested -= 1\n                continue = false\n                not_full.signal\n                break\n              end\n\n              if @shutdown\n                continue = false\n                break\n              end\n\n              @waiting += 1 # `@waiting` is the waiting threads count.\n              not_full.signal\n              \n              # This line will cause current thread waiting\n              # until `not_empty.signal` executed in some other place to wake it up .\n              # Actually, `not_empty.signal` is located at `def \u0026lt;\u0026lt;(work)` in the same file.\n              # You can search `def \u0026lt;\u0026lt;(work)` in this document.\n              # Method `\u0026lt;\u0026lt;` is used in method `handle_servers`: `pool \u0026lt;\u0026lt; client` in Puma::Server#run.\n              # `pool \u0026lt;\u0026lt; client` means add a request to the thread pool, \n              # and then the waked up thread will process the request. \n              not_empty.wait mutex\n              \n              @waiting -= 1\n            end\n\n            # `work` is the request (in Puma, it's Puma::Client instance) which need to be processed.\n            work = todo.shift if continue  \n          end\n\n          break unless continue\n\n          if @clean_thread_locals\n            ThreadPool.clean_thread_locals\n          end\n\n          begin\n            # `block.call` will switch program to the block definition part.\n            # The block definition part is in `Puma::Server#run`:\n            # @thread_pool = ThreadPool.new(@min_threads,\n            #                               @max_threads,\n            #                               IOBuffer) do |client, buffer| #...; end\n            # So please search `ThreadPool.new` in this document to look back.\n            block.call(work, *extra)\n          rescue Exception =\u0026gt; e\n            STDERR.puts \u0026quot;Error reached top of thread-pool: #{e.message} (#{e.class})\u0026quot;\n          end\n        end\n\n        mutex.synchronize do\n          @spawned -= 1\n          @workers.delete th\n        end\n      end # end of the Thread.new.\n\n      @workers \u0026lt;\u0026lt; th\n\n      th\n    end\n    \n    def wait_until_not_full\n      @mutex.synchronize do\n        while true\n          return if @shutdown\n\n          # If we can still spin up new threads and there\n          # is work queued that cannot be handled by waiting\n          # threads, then accept more work until we would\n          # spin up the max number of threads.\n          return if @todo.size - @waiting \u0026lt; @max - @spawned\n\n          @not_full.wait @mutex \n        end\n      end\n    end\n    \n    # Add +work+ to the todo list for a Thread to pickup and process.\n    def \u0026lt;\u0026lt;(work)\n      @mutex.synchronize do\n        if @shutdown\n          raise \u0026quot;Unable to add work while shutting down\u0026quot;\n        end\n        \n        # work: #\u0026lt;Puma::Client:0x00007ff114ece6b0\u0026gt;\n        # You can look upon Puma::Client instance as a request.\n        @todo \u0026lt;\u0026lt; work\n\n        if @waiting \u0026lt; @todo.size and @spawned \u0026lt; @max\n          spawn_thread # Create one more thread to process request. \n        end\n\n        # Wake up the waiting thread to process the request.\n        # The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.\n        # This code is in `spawn_thread`:\n        # while true \n        #   # ...\n        #   not_empty.wait mutex\n        #   # ... \n        #   block.call(work, *extra) # This line will process the request.\n        # end \n        @not_empty.signal  \n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/thread_pool.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Maintain a minimum of +min+ and maximum of +max+ threads\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# in the pool.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# The block passed is the work that will be performed in each\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# thread.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emin\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emax\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eextra\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#..\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eMutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@todo\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @todo is requests (in Puma, they are Puma::Client instances) which need to be processed.  \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# the count of @spawned threads\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@min\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eInteger\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emin\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @min threads count\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@max\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eInteger\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emax\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @max threads count\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@block\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# block will be called in method `spawn_thread` to processed a request.    \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@reaper\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@min\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etimes\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-en\"\u003espawn_thread\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Puma spawns @min count threads.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003espawn_thread\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e += \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Create a new Thread now.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# The block of the thread will be executed immediately and separately from the calling thread (main thread).\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003espawned\u003c/span\u003e|\n        \u003cspan class=\"pl-c\"\u003e# Thread name is new in Ruby 2.3\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ename\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'puma %03i'\u003c/span\u003e % \u003cspan class=\"pl-s1\"\u003espawned\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erespond_to?\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e:name=\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@block\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003eextra\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@extra\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emap\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e| \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# Pay attention to here: \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'while true' means this part will always be running.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# And there will be @min count threads always running!\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Puma uses these threads to process requests. \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# The line: 'not_empty.wait(mutex)' will make current thread waiting.  \u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-en\"\u003etodo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eempty?\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@trim_requested\u003c/span\u003e \u0026gt; \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\n                \u003cspan class=\"pl-c1\"\u003e@trim_requested\u003c/span\u003e -= \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n                \u003cspan class=\"pl-en\"\u003enot_full\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esignal\u003c/span\u003e\n                \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n              \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@shutdown\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n                \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n              \u003cspan class=\"pl-c1\"\u003e@waiting\u003c/span\u003e += \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# `@waiting` is the waiting threads count.\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003enot_full\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esignal\u003c/span\u003e\n              \n              \u003cspan class=\"pl-c\"\u003e# This line will cause current thread waiting\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# until `not_empty.signal` executed in some other place to wake it up .\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# Actually, `not_empty.signal` is located at `def \u0026lt;\u0026lt;(work)` in the same file.\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# You can search `def \u0026lt;\u0026lt;(work)` in this document.\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# Method `\u0026lt;\u0026lt;` is used in method `handle_servers`: `pool \u0026lt;\u0026lt; client` in Puma::Server#run.\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# `pool \u0026lt;\u0026lt; client` means add a request to the thread pool, \u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# and then the waked up thread will process the request. \u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003enot_empty\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewait\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\n              \n              \u003cspan class=\"pl-c1\"\u003e@waiting\u003c/span\u003e -= \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n            \u003cspan class=\"pl-c\"\u003e# `work` is the request (in Puma, it's Puma::Client instance) which need to be processed.\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003etodo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eshift\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e  \n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@clean_thread_locals\u003c/span\u003e\n            \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclean_thread_locals\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# `block.call` will switch program to the block definition part.\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# The block definition part is in `Puma::Server#run`:\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# @thread_pool = ThreadPool.new(@min_threads,\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e#                               @max_threads,\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e#                               IOBuffer) do |client, buffer| #...; end\u003c/span\u003e\n            \u003cspan class=\"pl-c\"\u003e# So please search `ThreadPool.new` in this document to look back.\u003c/span\u003e\n            \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecall\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eextra\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\n            \u003cspan class=\"pl-c1\"\u003eSTDERR\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Error reached top of thread-pool: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003emessage\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ee\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclass\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e)\"\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e -= \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edelete\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# end of the Thread.new.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n\n      \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ewait_until_not_full\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@shutdown\u003c/span\u003e\n\n          \u003cspan class=\"pl-c\"\u003e# If we can still spin up new threads and there\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# is work queued that cannot be handled by waiting\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# threads, then accept more work until we would\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# spin up the max number of threads.\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@todo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esize\u003c/span\u003e - \u003cspan class=\"pl-c1\"\u003e@waiting\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-c1\"\u003e@max\u003c/span\u003e - \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e\n\n          \u003cspan class=\"pl-c1\"\u003e@not_full\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewait\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e \n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Add +work+ to the todo list for a Thread to pickup and process.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u0026lt;\u0026lt;\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@shutdown\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Unable to add work while shutting down\"\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n        \u003cspan class=\"pl-c\"\u003e# work: #\u0026lt;Puma::Client:0x00007ff114ece6b0\u0026gt;\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# You can look upon Puma::Client instance as a request.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@todo\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e\n\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@waiting\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-c1\"\u003e@todo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eand\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-c1\"\u003e@max\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003espawn_thread\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Create one more thread to process request. \u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# Wake up the waiting thread to process the request.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# This code is in `spawn_thread`:\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# while true \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   # ...\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   not_empty.wait mutex\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   # ... \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   block.call(work, *extra) # This line will process the request.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# end \u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@not_empty\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esignal\u003c/span\u003e  \n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConclusion\u003c/h3\u003e\u003ca id=\"user-content-conclusion\" class=\"anchor\" aria-label=\"Permalink: Conclusion\" href=\"#conclusion\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn conclusion, \u003ccode\u003e$ rails server\u003c/code\u003e will execute \u003ccode\u003eRails::Command::ServerCommand#perform\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn \u003ccode\u003e#perform\u003c/code\u003e, call \u003ccode\u003eRails::Server#start\u003c/code\u003e. Then call \u003ccode\u003eRack::Server#start\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThen call \u003ccode\u003eRack::Handler::Puma.run(YourProject::Application.new)\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn \u003ccode\u003e.run\u003c/code\u003e, Puma will new a always running Thread for \u003ccode\u003eios = IO.select(#\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;)\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRequest is created from \u003ccode\u003eios\u003c/code\u003e object.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA thread in Puma threadPool will process the request.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe thread will invoke Rack apps' \u003ccode\u003ecall\u003c/code\u003e to get the response for the request.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExiting Puma\u003c/h3\u003e\u003ca id=\"user-content-exiting-puma\" class=\"anchor\" aria-label=\"Permalink: Exiting Puma\" href=\"#exiting-puma\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eProcess and Thread\u003c/h4\u003e\u003ca id=\"user-content-process-and-thread\" class=\"anchor\" aria-label=\"Permalink: Process and Thread\" href=\"#process-and-thread\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBecause Puma is using multiple threads, we need to have some basic concepts about Process and Thread.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis link is good for you to obtain the concepts: \u003ca href=\"https://stackoverflow.com/questions/4894609/will-a-cpu-process-have-at-least-one-thread\" rel=\"nofollow\"\u003eProcess and Thread\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn the next part, you will often see \u003ccode\u003ethread.join\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eI will use two simple example to tell what does \u003ccode\u003ethread.join\u003c/code\u003e do.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample one\u003c/h5\u003e\u003ca id=\"user-content-example-one\" class=\"anchor\" aria-label=\"Permalink: Example one\" href=\"#example-one\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTry to run \u003ccode\u003etest_thread_join.rb\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./test_thread_join.rb\nthread = Thread.new() do\n  3.times do |n|\n    puts \u0026quot;~~~~ \u0026quot; + n.to_s\n  end\nend\n\n# sleep 1\nputs \u0026quot;==== I am the main thread.\u0026quot;\n\n# thread.join # Try to uncomment these two lines to see the differences.\n# puts \u0026quot;==== after thread.join\u0026quot;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./test_thread_join.rb\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n  \u003cspan class=\"pl-c1\"\u003e3\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etimes\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e|\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"~~~~ \"\u003c/span\u003e + \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_s\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# sleep 1\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"==== I am the main thread.\"\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# thread.join # Try to uncomment these two lines to see the differences.\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e# puts \"==== after thread.join\"\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou will find that if there is no \u003ccode\u003ethread.join\u003c/code\u003e, you can see\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"==== I am the main thread.\n==== after thread.join\n~~~~ 0\n~~~~ 1\n~~~~ 2\"\u003e\u003cpre lang=\"log\" class=\"notranslate\"\u003e\u003ccode\u003e==== I am the main thread.\n==== after thread.join\n~~~~ 0\n~~~~ 1\n~~~~ 2\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003ein console.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAfter you added \u003ccode\u003ethread.join\u003c/code\u003e, you can see:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"==== I am the main thread.\n~~~~ 0\n~~~~ 1\n~~~~ 2\n==== after thread.join\"\u003e\u003cpre lang=\"log\" class=\"notranslate\"\u003e\u003ccode\u003e==== I am the main thread.\n~~~~ 0\n~~~~ 1\n~~~~ 2\n==== after thread.join\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003ein console.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample two\u003c/h5\u003e\u003ca id=\"user-content-example-two\" class=\"anchor\" aria-label=\"Permalink: Example two\" href=\"#example-two\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTry to run \u003ccode\u003etest_thread_join2.rb\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# ./test_thread_join2.rb\narr = [\n  Thread.new do\n    puts 'I am arr[0]'\n    sleep 1\n    puts 'After arr[0]'\n  end,\n  Thread.new do\n    puts 'I am arr[1]'\n    sleep 5\n    puts 'After arr[1]'\n  end,\n  Thread.new do\n    puts 'I am arr[2]'\n    sleep 8\n    puts 'After arr[2]'\n  end\n]\n\nputs \u0026quot;Thread.list.size:  #{Thread.list.size}\u0026quot; # returns 4 (including the main thread)\n\nsleep 2\n\narr.each { |thread| puts \u0026quot;~~~~~ #{thread}\u0026quot; }\n\nputs \u0026quot;Thread.list.size:  #{Thread.list.size}\u0026quot; # returns 3 (because arr[0] is dead)\n\narr[1].join # uncomment to see differences\n\narr.each { |thread| puts \u0026quot;~~~~~ #{thread}\u0026quot; }\n\nsleep 7\nputs \u0026quot;Exit main thread\u0026quot;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# ./test_thread_join2.rb\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003earr\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\n  \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'I am arr[0]'\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003esleep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'After arr[0]'\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'I am arr[1]'\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003esleep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e5\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'After arr[1]'\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'I am arr[2]'\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003esleep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e8\u003c/span\u003e\n    \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e'After arr[2]'\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Thread.list.size:  \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003elist\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# returns 4 (including the main thread)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003esleep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e2\u003c/span\u003e\n\n\u003cspan class=\"pl-s1\"\u003earr\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e| \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"~~~~~ \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Thread.list.size:  \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003elist\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# returns 3 (because arr[0] is dead)\u003c/span\u003e\n\n\u003cspan class=\"pl-s1\"\u003earr\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejoin\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# uncomment to see differences\u003c/span\u003e\n\n\u003cspan class=\"pl-s1\"\u003earr\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e| \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"~~~~~ \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003esleep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e7\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Exit main thread\"\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSend \u003ccode\u003eSIGTERM\u003c/code\u003e to Puma\u003c/h4\u003e\u003ca id=\"user-content-send-sigterm-to-puma\" class=\"anchor\" aria-label=\"Permalink: Send SIGTERM to Puma\" href=\"#send-sigterm-to-puma\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen you stop Puma by running \u003ccode\u003e$ kill -s SIGTERM puma_process_id\u003c/code\u003e, you will enter \u003ccode\u003esetup_signals\u003c/code\u003e in \u003ccode\u003ePuma::Launcher#run\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/launcher.rb\nmodule Puma\n  # Puma::Launcher is the single entry point for starting a Puma server based on user\n  # configuration.\n  class Launcher\n    def run\n      #...\n\n      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. \n      setup_signals # Let's step into this line.\n      \n      set_process_title\n      \n      @runner.run\n\n      # ...\n    end\n    \n    # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.\n    # Signal.list #=\u0026gt; {\u0026quot;EXIT\u0026quot;=\u0026gt;0, \u0026quot;HUP\u0026quot;=\u0026gt;1, \u0026quot;INT\u0026quot;=\u0026gt;2, \u0026quot;QUIT\u0026quot;=\u0026gt;3, \u0026quot;ILL\u0026quot;=\u0026gt;4, \u0026quot;TRAP\u0026quot;=\u0026gt;5, \u0026quot;IOT\u0026quot;=\u0026gt;6, \u0026quot;ABRT\u0026quot;=\u0026gt;6, \u0026quot;FPE\u0026quot;=\u0026gt;8, \u0026quot;KILL\u0026quot;=\u0026gt;9, \u0026quot;BUS\u0026quot;=\u0026gt;7, \u0026quot;SEGV\u0026quot;=\u0026gt;11, \u0026quot;SYS\u0026quot;=\u0026gt;31, \u0026quot;PIPE\u0026quot;=\u0026gt;13, \u0026quot;ALRM\u0026quot;=\u0026gt;14, \u0026quot;TERM\u0026quot;=\u0026gt;15, \u0026quot;URG\u0026quot;=\u0026gt;23, \u0026quot;STOP\u0026quot;=\u0026gt;19, \u0026quot;TSTP\u0026quot;=\u0026gt;20, \u0026quot;CONT\u0026quot;=\u0026gt;18, \u0026quot;CHLD\u0026quot;=\u0026gt;17, \u0026quot;CLD\u0026quot;=\u0026gt;17, \u0026quot;TTIN\u0026quot;=\u0026gt;21, \u0026quot;TTOU\u0026quot;=\u0026gt;22, \u0026quot;IO\u0026quot;=\u0026gt;29, \u0026quot;XCPU\u0026quot;=\u0026gt;24, \u0026quot;XFSZ\u0026quot;=\u0026gt;25, \u0026quot;VTALRM\u0026quot;=\u0026gt;26, \u0026quot;PROF\u0026quot;=\u0026gt;27, \u0026quot;WINCH\u0026quot;=\u0026gt;28, \u0026quot;USR1\u0026quot;=\u0026gt;10, \u0026quot;USR2\u0026quot;=\u0026gt;12, \u0026quot;PWR\u0026quot;=\u0026gt;30, \u0026quot;POLL\u0026quot;=\u0026gt;29}\n    # Press `Control + C` to quit means 'SIGINT'.\n    def setup_signals\n      begin\n        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \u0026quot;SIGTERM\u0026quot;`.\n        Signal.trap \u0026quot;SIGTERM\u0026quot; do\n          graceful_stop # Let's step into this line.\n\n          raise SignalException, \u0026quot;SIGTERM\u0026quot;\n        end\n      rescue Exception\n        log \u0026quot;*** SIGTERM not implemented, signal based gracefully stopping unavailable!\u0026quot;\n      end\n            \n      begin\n        Signal.trap \u0026quot;SIGUSR2\u0026quot; do\n          restart\n        end\n      rescue Exception\n        log \u0026quot;*** SIGUSR2 not implemented, signal based restart unavailable!\u0026quot;\n      end\n\n      begin\n        Signal.trap \u0026quot;SIGUSR1\u0026quot; do\n          phased_restart\n        end\n      rescue Exception\n        log \u0026quot;*** SIGUSR1 not implemented, signal based restart unavailable!\u0026quot;\n      end\n\n      begin\n        Signal.trap \u0026quot;SIGINT\u0026quot; do\n          if Puma.jruby?\n            @status = :exit\n            graceful_stop\n            exit\n          end\n\n          stop\n        end\n      rescue Exception\n        log \u0026quot;*** SIGINT not implemented, signal based gracefully stopping unavailable!\u0026quot;\n      end\n\n      begin\n        Signal.trap \u0026quot;SIGHUP\u0026quot; do\n          if @runner.redirected_io?\n            @runner.redirect_io\n          else\n            stop\n          end\n        end\n      rescue Exception\n        log \u0026quot;*** SIGHUP not implemented, signal based logs reopening unavailable!\u0026quot;\n      end\n    end\n    \n    def graceful_stop\n      # @runner: instance of Puma::Single (for this example)\n      @runner.stop_blocked # Let's step into this line.\n      log \u0026quot;=== puma shutdown: #{Time.now} ===\u0026quot;\n      log \u0026quot;- Goodbye!\u0026quot;\n    end\n  end\nend\n\n# .gems/puma-3.12.0/lib/puma/launcher.rb\nmodule Puma\n  class Single \u0026lt; Runner\n    def run\n      # ...\n\n      # @server: Puma::Server.new(app, @launcher.events, @options)\n      @server = server = start_server # Let's step into this line.\n\n      # ...\n      thread = server.run\n      \n      # This line will suspend the main thread execution.\n      # And the `thread`'s block (which is the method `handle_servers`) will be executed.  \n      thread.join\n    end\n      \n    def stop_blocked\n      log \u0026quot;- Gracefully stopping, waiting for requests to finish\u0026quot;\n      @control.stop(true) if @control\n      # @server: instance of Puma::Server\n      @server.stop(true) # Let's step into this line\n    end\n  end\nend\n\n# .gems/puma-3.12.0/lib/puma/server.rb\nmodule Puma\n  class Server\n    def initialize(app, events=Events.stdio, options={})\n      # 'Puma::Util.pipe' returns `IO.pipe`.\n      @check, @notify = Puma::Util.pipe # @check, @notify is a pair.\n\n      @status = :stop\n    end\n      \n    def run(background=true)\n      # ...\n      @thread_pool = ThreadPool.new(@min_threads,\n                                    @max_threads,\n                                    IOBuffer) do |client, buffer|\n\n        #...\n        # Process the request.\n        process_client(client, buffer)  \n        #...\n      end\n      \n      # 'Thread.current.object_id' returns '70144214949920', \n      # which is the same as the 'Thread.current.object_id' in Puma::Server#stop.\n      # Current thread is the main thread here.\n      puts \u0026quot;#{Thread.current.object_id}\u0026quot;\n      \n      # The created @thread is the @thread in `stop` method below.\n      @thread = Thread.new {\n        # FYI, this is in the Puma starting process.      \n        # 'Thread.current.object_id' returns '70144220123860', \n        # which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run\n        # def handle_servers\n        #   begin\n        #     # ...\n        #   ensure\n        #     # FYI, the 'ensure' part is in the Puma stopping process.\n        #     puts \u0026quot;#{Thread.current.object_id}\u0026quot; # returns '70144220123860' too.\n        #   end\n        # end\n        puts \u0026quot;#{Thread.current.object_id}\u0026quot; # returns '70144220123860'\n        \n        handle_servers\n      }\n      return @thread\n    end\n      \n    # Stops the acceptor thread and then causes the worker threads to finish\n    # off the request queue before finally exiting.\n    def stop(sync=false)\n      # This line will set '@status = :stop',\n      # and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.\n      # So that the code after `ios = IO.select sockets` will be executed.   \n      notify_safely(STOP_COMMAND) # Let's step into this line.\n      \n      # 'Thread.current.object_id' returns '70144214949920', \n      # which is the same as the 'Thread.current.object_id' in Puma::Server#run.\n      # Current thread is exactly the main thread here.\n      puts \u0026quot;#{Thread.current.object_id}\u0026quot;\n      \n      # The @thread is just the always running Thread created in `Puma::Server#run`.\n      # Please look at method `Puma::Server#run`.\n      # `@thread.join` will suspend the main thread execution.\n      # And the code in @thread will continue be executed.\n      @thread.join if @thread \u0026amp;\u0026amp; sync\n    end\n    \n    def notify_safely(message)\n      @notify \u0026lt;\u0026lt; message\n    end\n    \n    def handle_servers\n      begin\n        check = @check\n        # sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;]\n        sockets = [check] + @binder.ios\n        pool = @thread_pool\n        #...\n \n        while @status == :run\n          # After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.\n          # FYI, `@check, @notify = IO.pipe`.\n          # def notify_safely(message)\n          #   @notify \u0026lt;\u0026lt; message\n          # end\n          # sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;]\n          ios = IO.select sockets\n            \n          ios.first.each do |sock|\n            if sock == check\n              # The @status is updated to :stop for this example in `handle_check`.\n              break if handle_check # Let's step into this line.\n            else\n              if io = sock.accept_nonblock\n                client = Client.new(io, @binder.env(sock))\n                \n                # ...\n                pool \u0026lt;\u0026lt; client\n                pool.wait_until_not_full\n              end\n            end\n          end\n        end\n        \n        # Let's step into `graceful_shutdown`.\n        graceful_shutdown if @status == :stop || @status == :restart\n        \n      # ...\n      ensure\n        # FYI, the 'ensure' part is in the Puma stopping process.\n        # 'Thread.current.object_id' returns '70144220123860', \n        # which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run\n        # @thread = Thread.new do\n        #   # FYI, this is in the Puma starting process.\n        #   puts \u0026quot;#{Thread.current.object_id}\u0026quot; # returns '70144220123860'\n        #   handle_servers\n        # end\n        puts \u0026quot;#{Thread.current.object_id}\u0026quot;\n          \n        @check.close\n        @notify.close\n\n        # ...\n      end\n    end\n    \n    def handle_check\n      cmd = @check.read(1)\n\n      case cmd\n      when STOP_COMMAND\n        @status = :stop # The @status is updated to :stop for this example. \n        return true\n      when HALT_COMMAND\n        @status = :halt\n        return true\n      when RESTART_COMMAND\n        @status = :restart\n        return true\n      end\n\n      return false\n    end\n    \n    def graceful_shutdown\n      if @thread_pool\n        @thread_pool.shutdown # Let's step into this line.\n      end\n    end    \n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/launcher.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Puma::Launcher is the single entry point for starting a Puma server based on user\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# configuration.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eLauncher\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003esetup_signals\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003eset_process_title\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-c\"\u003e# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Signal.list #=\u0026gt; {\"EXIT\"=\u0026gt;0, \"HUP\"=\u0026gt;1, \"INT\"=\u0026gt;2, \"QUIT\"=\u0026gt;3, \"ILL\"=\u0026gt;4, \"TRAP\"=\u0026gt;5, \"IOT\"=\u0026gt;6, \"ABRT\"=\u0026gt;6, \"FPE\"=\u0026gt;8, \"KILL\"=\u0026gt;9, \"BUS\"=\u0026gt;7, \"SEGV\"=\u0026gt;11, \"SYS\"=\u0026gt;31, \"PIPE\"=\u0026gt;13, \"ALRM\"=\u0026gt;14, \"TERM\"=\u0026gt;15, \"URG\"=\u0026gt;23, \"STOP\"=\u0026gt;19, \"TSTP\"=\u0026gt;20, \"CONT\"=\u0026gt;18, \"CHLD\"=\u0026gt;17, \"CLD\"=\u0026gt;17, \"TTIN\"=\u0026gt;21, \"TTOU\"=\u0026gt;22, \"IO\"=\u0026gt;29, \"XCPU\"=\u0026gt;24, \"XFSZ\"=\u0026gt;25, \"VTALRM\"=\u0026gt;26, \"PROF\"=\u0026gt;27, \"WINCH\"=\u0026gt;28, \"USR1\"=\u0026gt;10, \"USR2\"=\u0026gt;12, \"PWR\"=\u0026gt;30, \"POLL\"=\u0026gt;29}\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Press `Control + C` to quit means 'SIGINT'.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esetup_signals\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \"SIGTERM\"`.\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGTERM\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003egraceful_stop\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n          \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSignalException\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGTERM\"\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGTERM not implemented, signal based gracefully stopping unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n            \n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGUSR2\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003erestart\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGUSR2 not implemented, signal based restart unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGUSR1\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003ephased_restart\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGUSR1 not implemented, signal based restart unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGINT\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejruby?\u003c/span\u003e\n            \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:exit\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003egraceful_stop\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003eexit\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGINT not implemented, signal based gracefully stopping unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGHUP\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eredirected_io?\u003c/span\u003e\n            \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eredirect_io\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n            \u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGHUP not implemented, signal based logs reopening unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003egraceful_stop\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# @runner: instance of Puma::Single (for this example)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estop_blocked\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"=== puma shutdown: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eTime\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enow\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e ===\"\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"- Goodbye!\"\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/launcher.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSingle\u003c/span\u003e \u0026lt; \u003cspan class=\"pl-v\"\u003eRunner\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# @server: Puma::Server.new(app, @launcher.events, @options)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@server\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart_server\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eserver\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# This line will suspend the main thread execution.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# And the `thread`'s block (which is the method `handle_servers`) will be executed.  \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejoin\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estop_blocked\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"- Gracefully stopping, waiting for requests to finish\"\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@control\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@control\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# @server: instance of Puma::Server\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@server\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/server.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eServer\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eapp\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eevents\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eEvents\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003estdio\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# 'Puma::Util.pipe' returns `IO.pipe`.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@check\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@notify\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e::\u003cspan class=\"pl-v\"\u003eUtil\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epipe\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @check, @notify is a pair.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:stop\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ebackground\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@min_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n                                    \u003cspan class=\"pl-c1\"\u003e@max_threads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n                                    \u003cspan class=\"pl-v\"\u003eIOBuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e|\n\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# Process the request.\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eprocess_client\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e  \n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# 'Thread.current.object_id' returns '70144214949920', \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# which is the same as the 'Thread.current.object_id' in Puma::Server#stop.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Current thread is the main thread here.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eobject_id\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# The created @thread is the @thread in `stop` method below.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# FYI, this is in the Puma starting process.      \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'Thread.current.object_id' returns '70144220123860', \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# def handle_servers\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   begin\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#     # ...\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   ensure\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#     # FYI, the 'ensure' part is in the Puma stopping process.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#     puts \"#{Thread.current.object_id}\" # returns '70144220123860' too.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   end\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# end\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eobject_id\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# returns '70144220123860'\u003c/span\u003e\n        \n        \u003cspan class=\"pl-en\"\u003ehandle_servers\u003c/span\u003e\n      \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \n    \u003cspan class=\"pl-c\"\u003e# Stops the acceptor thread and then causes the worker threads to finish\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# off the request queue before finally exiting.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estop\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esync\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# This line will set '@status = :stop',\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# So that the code after `ios = IO.select sockets` will be executed.   \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003enotify_safely\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eSTOP_COMMAND\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# 'Thread.current.object_id' returns '70144214949920', \u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# which is the same as the 'Thread.current.object_id' in Puma::Server#run.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Current thread is exactly the main thread here.\u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eobject_id\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# The @thread is just the always running Thread created in `Puma::Server#run`.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# Please look at method `Puma::Server#run`.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# `@thread.join` will suspend the main thread execution.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# And the code in @thread will continue be executed.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejoin\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"pl-s1\"\u003esync\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003enotify_safely\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@notify\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_servers\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003echeck\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@check\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;]\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003esockets\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003echeck\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e + \u003cspan class=\"pl-c1\"\u003e@binder\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eios\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n \n        \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e == \u003cspan class=\"pl-pds\"\u003e:run\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# FYI, `@check, @notify = IO.pipe`.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# def notify_safely(message)\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   @notify \u0026lt;\u0026lt; message\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# end\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# sockets: [#\u0026lt;IO:fd 23\u0026gt;, #\u0026lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u0026gt;]\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003eios\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eIO\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esockets\u003c/span\u003e\n            \n          \u003cspan class=\"pl-s1\"\u003eios\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efirst\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e|\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e == \u003cspan class=\"pl-s1\"\u003echeck\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# The @status is updated to :stop for this example in `handle_check`.\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_check\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eio\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eaccept_nonblock\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eClient\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eio\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@binder\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eenv\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n                \n                \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003eclient\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003epool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewait_until_not_full\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n        \n        \u003cspan class=\"pl-c\"\u003e# Let's step into `graceful_shutdown`.\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003egraceful_shutdown\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e == \u003cspan class=\"pl-pds\"\u003e:stop\u003c/span\u003e || \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e == \u003cspan class=\"pl-pds\"\u003e:restart\u003c/span\u003e\n        \n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eensure\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# FYI, the 'ensure' part is in the Puma stopping process.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# 'Thread.current.object_id' returns '70144220123860', \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# @thread = Thread.new do\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   # FYI, this is in the Puma starting process.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   puts \"#{Thread.current.object_id}\" # returns '70144220123860'\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#   handle_servers\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# end\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eobject_id\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n          \n        \u003cspan class=\"pl-c1\"\u003e@check\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclose\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@notify\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclose\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ehandle_check\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ecmd\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@check\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ecase\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecmd\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eSTOP_COMMAND\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:stop\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# The @status is updated to :stop for this example. \u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eHALT_COMMAND\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:halt\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eRESTART_COMMAND\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@status\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-pds\"\u003e:restart\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003egraceful_shutdown\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@thread_pool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eshutdown\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e    \n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"module Puma\n  class ThreadPool\n    # Tell all threads in the pool to exit and wait for them to finish.\n    def shutdown(timeout=-1)\n      threads = @mutex.synchronize do\n        @shutdown = true\n        # `broadcast` will wakes up all threads waiting for this lock.\n        @not_empty.broadcast\n        @not_full.broadcast\n\n        # ...\n        \n        # dup workers so that we join them all safely\n        # @workers is an array.   \n        # @workers.dup will not create new thread.\n        # @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). \n        # So ues @workers.dup here.\n        @workers.dup\n      end\n\n      # Wait for threads to finish without force shutdown.\n      threads.each do |thread|\n        thread.join\n      end\n\n      @spawned = 0\n      @workers = []\n    end\n\n    def initialize(min, max, *extra, \u0026amp;block)\n      #..\n      @mutex = Mutex.new\n      @spawned = 0 # The count of @spawned threads.\n      @todo = [] # @todo is requests (in Puma, it's Puma::Client instance) which need to be processed.  \n      @min = Integer(min) # @min threads count\n      @block = block # block will be called in method `spawn_thread` to process a request.    \n      @workers = []\n\n      @mutex.synchronize do\n        @min.times { spawn_thread } # Puma spawns @min count threads.\n      end\n    end\n    \n    def spawn_thread\n      @spawned += 1\n\n      # Run a new Thread now.\n      # The block of the thread will be executed separately from the calling thread. \n      th = Thread.new(@spawned) do |spawned|\n        block = @block\n        mutex = @mutex\n        #...\n \n        while true\n          work = nil\n\n          continue = true\n\n          mutex.synchronize do\n            while todo.empty?\n              # ...\n \n              if @shutdown\n                continue = false\n                break\n              end\n\n              # ...\n              # After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.\n              # Ruby will continue to execute the next line here.\n              not_empty.wait mutex\n              \n              @waiting -= 1\n            end\n\n            # ...\n          end\n\n          break unless continue\n\n          # ...\n        end\n\n        mutex.synchronize do\n          @spawned -= 1\n          @workers.delete th\n        end\n      end # end of the Thread.new.\n\n      @workers \u0026lt;\u0026lt; th\n\n      th\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThreadPool\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e# Tell all threads in the pool to exit and wait for them to finish.\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eshutdown\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etimeout\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e-\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethreads\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@shutdown\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# `broadcast` will wakes up all threads waiting for this lock.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@not_empty\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebroadcast\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@not_full\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ebroadcast\u003c/span\u003e\n\n        \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \n        \u003cspan class=\"pl-c\"\u003e# dup workers so that we join them all safely\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# @workers is an array.   \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# @workers.dup will not create new thread.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). \u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# So ues @workers.dup here.\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edup\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Wait for threads to finish without force shutdown.\u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003ethreads\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eeach\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e|\n        \u003cspan class=\"pl-s1\"\u003ethread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ejoin\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einitialize\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emin\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emax\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e *\u003cspan class=\"pl-s1\"\u003eextra\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u0026amp;\u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#..\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eMutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# The count of @spawned threads.\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@todo\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @todo is requests (in Puma, it's Puma::Client instance) which need to be processed.  \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@min\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eInteger\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emin\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# @min threads count\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@block\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# block will be called in method `spawn_thread` to process a request.    \u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e@min\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etimes\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-en\"\u003espawn_thread\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Puma spawns @min count threads.\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003espawn_thread\u003c/span\u003e\n      \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e += \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Run a new Thread now.\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# The block of the thread will be executed separately from the calling thread. \u003c/span\u003e\n      \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eThread\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e |\u003cspan class=\"pl-s1\"\u003espawned\u003c/span\u003e|\n        \u003cspan class=\"pl-s1\"\u003eblock\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@block\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@mutex\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n \n        \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n          \u003cspan class=\"pl-s1\"\u003ework\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enil\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n\n          \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"pl-en\"\u003etodo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eempty?\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n \n              \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e@shutdown\u003c/span\u003e\n                \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n                \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e\n              \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n              \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.\u003c/span\u003e\n              \u003cspan class=\"pl-c\"\u003e# Ruby will continue to execute the next line here.\u003c/span\u003e\n              \u003cspan class=\"pl-en\"\u003enot_empty\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ewait\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\n              \n              \u003cspan class=\"pl-c1\"\u003e@waiting\u003c/span\u003e -= \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n            \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n          \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n          \u003cspan class=\"pl-k\"\u003ebreak\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eunless\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econtinue\u003c/span\u003e\n\n          \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\n        \u003cspan class=\"pl-s1\"\u003emutex\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003esynchronize\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@spawned\u003c/span\u003e -= \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n          \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003edelete\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# end of the Thread.new.\u003c/span\u003e\n\n      \u003cspan class=\"pl-c1\"\u003e@workers\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n\n      \u003cspan class=\"pl-s1\"\u003eth\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSo all the threads in the ThreadPool joined and finished.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet's inspect the caller in block of \u003ccode\u003eSignal.trap \"SIGTERM\"\u003c/code\u003e below.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-ruby notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# .gems/puma-3.12.0/lib/puma/launcher.rb\nmodule Puma\n  # Puma::Launcher is the single entry point for starting a Puma server based on user\n  # configuration.\n  class Launcher\n    def run\n      #...\n\n      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. \n      setup_signals # Let's step into this line.\n      \n      set_process_title\n      \n      # Process.pid: 42264 \n      puts \u0026quot;Process.pid: #{Process.pid}\u0026quot;\n      \n      @runner.run\n\n      # ...\n    end\n    \n    def setup_signals\n      # ...\n      begin\n        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \u0026quot;SIGTERM\u0026quot;`.\n        Signal.trap \u0026quot;SIGTERM\u0026quot; do\n          # I inspect `caller` to see the caller stack.\n          # caller: [\n          #   \u0026quot;../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'\u0026quot;, \n          #   \u0026quot;../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'\u0026quot;,\n          #   \u0026quot;../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'\u0026quot;,\n          #   \u0026quot;../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'\u0026quot;,\n          #   \u0026quot;../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'\u0026quot;,\n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\u0026quot;, \n          #   \u0026quot;../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\u0026quot;, \n          #   \u0026quot;../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\u0026quot;, \n          #   \u0026quot;../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\u0026quot;, \n          #   \u0026quot;../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u0026lt;top (required)\u0026gt;'\u0026quot;, \n          #   \u0026quot;../path/to/your_project/bin/rails:5:in `require'\u0026quot;, \n          #   \u0026quot;../path/to/your_project/bin/rails:5:in `\u0026lt;main\u0026gt;'\u0026quot;\n          # ]\n          puts \u0026quot;caller: #{caller.inspect}\u0026quot;\n          \n          # Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.\n          puts \u0026quot;Process.pid: #{Process.pid}\u0026quot;\n          \n          graceful_stop\n          \n          # This SignalException is not rescued in the caller stack.\n          # So in the the caller stack, Ruby will goto the `ensure` part in\n          # \u0026quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\u0026quot;.\n          # So the last code executed is `puts \u0026quot;Exiting\u0026quot; unless @options \u0026amp;\u0026amp; options[:daemonize]`\n          # when running `$ kill -s SIGTERM puma_process_id`.\n          # You can search `puts \u0026quot;Exiting\u0026quot;` in this document to see it.\n          raise SignalException, \u0026quot;SIGTERM\u0026quot;\n        end\n      rescue Exception\n        # This `rescue` is only for `Signal.trap \u0026quot;SIGTERM\u0026quot;`, not for `raise SignalException, \u0026quot;SIGTERM\u0026quot;`.\n        log \u0026quot;*** SIGTERM not implemented, signal based gracefully stopping unavailable!\u0026quot;\n      end\n    end\n  end\nend\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e# .gems/puma-3.12.0/lib/puma/launcher.rb\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003emodule\u003c/span\u003e \u003cspan class=\"pl-v\"\u003ePuma\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# Puma::Launcher is the single entry point for starting a Puma server based on user\u003c/span\u003e\n  \u003cspan class=\"pl-c\"\u003e# configuration.\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eLauncher\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e#...\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003esetup_signals\u003c/span\u003e \u003cspan class=\"pl-c\"\u003e# Let's step into this line.\u003c/span\u003e\n      \n      \u003cspan class=\"pl-en\"\u003eset_process_title\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c\"\u003e# Process.pid: 42264 \u003c/span\u003e\n      \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Process.pid: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eProcess\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epid\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n      \n      \u003cspan class=\"pl-c1\"\u003e@runner\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e\n\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \n    \u003cspan class=\"pl-k\"\u003edef\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esetup_signals\u003c/span\u003e\n      \u003cspan class=\"pl-c\"\u003e# ...\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003ebegin\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \"SIGTERM\"`.\u003c/span\u003e\n        \u003cspan class=\"pl-v\"\u003eSignal\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003etrap\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGTERM\"\u003c/span\u003e \u003cspan class=\"pl-k\"\u003edo\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# I inspect `caller` to see the caller stack.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# caller: [\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'\",\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'\",\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'\",\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'\",\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u0026lt;top (required)\u0026gt;'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../path/to/your_project/bin/rails:5:in `require'\", \u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e#   \"../path/to/your_project/bin/rails:5:in `\u0026lt;main\u0026gt;'\"\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# ]\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"caller: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ecaller\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003einspect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n          \n          \u003cspan class=\"pl-c\"\u003e# Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eputs\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"Process.pid: \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-kos\"\u003e#{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eProcess\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epid\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/span\u003e\"\u003c/span\u003e\n          \n          \u003cspan class=\"pl-en\"\u003egraceful_stop\u003c/span\u003e\n          \n          \u003cspan class=\"pl-c\"\u003e# This SignalException is not rescued in the caller stack.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# So in the the caller stack, Ruby will goto the `ensure` part in\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\".\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# So the last code executed is `puts \"Exiting\" unless @options \u0026amp;\u0026amp; options[:daemonize]`\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# when running `$ kill -s SIGTERM puma_process_id`.\u003c/span\u003e\n          \u003cspan class=\"pl-c\"\u003e# You can search `puts \"Exiting\"` in this document to see it.\u003c/span\u003e\n          \u003cspan class=\"pl-en\"\u003eraise\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSignalException\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"SIGTERM\"\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003erescue\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eException\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e# This `rescue` is only for `Signal.trap \"SIGTERM\"`, not for `raise SignalException, \"SIGTERM\"`.\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003elog\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"*** SIGTERM not implemented, signal based gracefully stopping unavailable!\"\u003c/span\u003e\n      \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n  \u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eend\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWelcome to point out the mistakes in this article :)\u003c/p\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"Learn-Rails-by-Reading-Source-Code","fully_qualified_name":"Learn-Rails-by-Reading-Source-Code","kind":"section_1","ident_start":2,"ident_end":36,"extent_start":0,"extent_end":90433,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":36}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":2776,"utf16_col":0}}},{"name":"Table of Contents","fully_qualified_name":"Table of Contents","kind":"section_2","ident_start":247,"ident_end":264,"extent_start":244,"extent_end":1437,"ident_utf16":{"start":{"line_number":3,"utf16_col":3},"end":{"line_number":3,"utf16_col":20}},"extent_utf16":{"start":{"line_number":3,"utf16_col":0},"end":{"line_number":25,"utf16_col":0}}},{"name":"Part 0: Before reading Rails 5 source code","fully_qualified_name":"Part 0: Before reading Rails 5 source code","kind":"section_2","ident_start":1440,"ident_end":1482,"extent_start":1437,"extent_end":2212,"ident_utf16":{"start":{"line_number":25,"utf16_col":3},"end":{"line_number":25,"utf16_col":45}},"extent_utf16":{"start":{"line_number":25,"utf16_col":0},"end":{"line_number":47,"utf16_col":0}}},{"name":"What will you learn from this tutorial?","fully_qualified_name":"What will you learn from this tutorial?","kind":"section_3","ident_start":1821,"ident_end":1860,"extent_start":1817,"extent_end":2212,"ident_utf16":{"start":{"line_number":34,"utf16_col":4},"end":{"line_number":34,"utf16_col":43}},"extent_utf16":{"start":{"line_number":34,"utf16_col":0},"end":{"line_number":47,"utf16_col":0}}},{"name":"Part 1: Your app: an instance of YourProject::Application","fully_qualified_name":"Part 1: Your app: an instance of YourProject::Application","kind":"section_2","ident_start":2215,"ident_end":2272,"extent_start":2212,"extent_end":8280,"ident_utf16":{"start":{"line_number":47,"utf16_col":3},"end":{"line_number":47,"utf16_col":60}},"extent_utf16":{"start":{"line_number":47,"utf16_col":0},"end":{"line_number":272,"utf16_col":0}}},{"name":"Part 2: config","fully_qualified_name":"Part 2: config","kind":"section_2","ident_start":8283,"ident_end":8297,"extent_start":8280,"extent_end":10998,"ident_utf16":{"start":{"line_number":272,"utf16_col":3},"end":{"line_number":272,"utf16_col":17}},"extent_utf16":{"start":{"line_number":272,"utf16_col":0},"end":{"line_number":376,"utf16_col":0}}},{"name":"Part 3: Every request and response","fully_qualified_name":"Part 3: Every request and response","kind":"section_2","ident_start":11001,"ident_end":11035,"extent_start":10998,"extent_end":50626,"ident_utf16":{"start":{"line_number":376,"utf16_col":3},"end":{"line_number":376,"utf16_col":37}},"extent_utf16":{"start":{"line_number":376,"utf16_col":0},"end":{"line_number":1492,"utf16_col":0}}},{"name":"Puma","fully_qualified_name":"Puma","kind":"section_3","ident_start":11201,"ident_end":11205,"extent_start":11197,"extent_end":14420,"ident_utf16":{"start":{"line_number":385,"utf16_col":4},"end":{"line_number":385,"utf16_col":8}},"extent_utf16":{"start":{"line_number":385,"utf16_col":0},"end":{"line_number":489,"utf16_col":0}}},{"name":"Rack apps","fully_qualified_name":"Rack apps","kind":"section_3","ident_start":14424,"ident_end":14433,"extent_start":14420,"extent_end":24641,"ident_utf16":{"start":{"line_number":489,"utf16_col":4},"end":{"line_number":489,"utf16_col":13}},"extent_utf16":{"start":{"line_number":489,"utf16_col":0},"end":{"line_number":717,"utf16_col":0}}},{"name":"The core app: ActionDispatch::Routing::RouteSet instance","fully_qualified_name":"The core app: ActionDispatch::Routing::RouteSet instance","kind":"section_3","ident_start":24645,"ident_end":24701,"extent_start":24641,"extent_end":36034,"ident_utf16":{"start":{"line_number":717,"utf16_col":4},"end":{"line_number":717,"utf16_col":60}},"extent_utf16":{"start":{"line_number":717,"utf16_col":0},"end":{"line_number":1071,"utf16_col":0}}},{"name":"Render view","fully_qualified_name":"Render view","kind":"section_3","ident_start":36038,"ident_end":36049,"extent_start":36034,"extent_end":47110,"ident_utf16":{"start":{"line_number":1071,"utf16_col":4},"end":{"line_number":1071,"utf16_col":15}},"extent_utf16":{"start":{"line_number":1071,"utf16_col":0},"end":{"line_number":1389,"utf16_col":0}}},{"name":"How can instance variables defined in Controller be accessed in view file?","fully_qualified_name":"How can instance variables defined in Controller be accessed in view file?","kind":"section_3","ident_start":47114,"ident_end":47188,"extent_start":47110,"extent_end":50626,"ident_utf16":{"start":{"line_number":1389,"utf16_col":4},"end":{"line_number":1389,"utf16_col":78}},"extent_utf16":{"start":{"line_number":1389,"utf16_col":0},"end":{"line_number":1492,"utf16_col":0}}},{"name":"Part 4: What does `$ rails server` do?","fully_qualified_name":"Part 4: What does `$ rails server` do?","kind":"section_2","ident_start":50629,"ident_end":50667,"extent_start":50626,"extent_end":90433,"ident_utf16":{"start":{"line_number":1492,"utf16_col":3},"end":{"line_number":1492,"utf16_col":41}},"extent_utf16":{"start":{"line_number":1492,"utf16_col":0},"end":{"line_number":2776,"utf16_col":0}}},{"name":"Thor","fully_qualified_name":"Thor","kind":"section_3","ident_start":52149,"ident_end":52153,"extent_start":52145,"extent_end":57711,"ident_utf16":{"start":{"line_number":1556,"utf16_col":4},"end":{"line_number":1556,"utf16_col":8}},"extent_utf16":{"start":{"line_number":1556,"utf16_col":0},"end":{"line_number":1727,"utf16_col":0}}},{"name":"Rails::Server#start","fully_qualified_name":"Rails::Server#start","kind":"section_3","ident_start":57715,"ident_end":57734,"extent_start":57711,"extent_end":60808,"ident_utf16":{"start":{"line_number":1727,"utf16_col":4},"end":{"line_number":1727,"utf16_col":23}},"extent_utf16":{"start":{"line_number":1727,"utf16_col":0},"end":{"line_number":1831,"utf16_col":0}}},{"name":"Starting Puma","fully_qualified_name":"Starting Puma","kind":"section_3","ident_start":60812,"ident_end":60825,"extent_start":60808,"extent_end":73917,"ident_utf16":{"start":{"line_number":1831,"utf16_col":4},"end":{"line_number":1831,"utf16_col":17}},"extent_utf16":{"start":{"line_number":1831,"utf16_col":0},"end":{"line_number":2234,"utf16_col":0}}},{"name":"Conclusion","fully_qualified_name":"Conclusion","kind":"section_3","ident_start":73921,"ident_end":73931,"extent_start":73917,"extent_end":74454,"ident_utf16":{"start":{"line_number":2234,"utf16_col":4},"end":{"line_number":2234,"utf16_col":14}},"extent_utf16":{"start":{"line_number":2234,"utf16_col":0},"end":{"line_number":2249,"utf16_col":0}}},{"name":"Exiting Puma","fully_qualified_name":"Exiting Puma","kind":"section_3","ident_start":74458,"ident_end":74470,"extent_start":74454,"extent_end":90433,"ident_utf16":{"start":{"line_number":2249,"utf16_col":4},"end":{"line_number":2249,"utf16_col":16}},"extent_utf16":{"start":{"line_number":2249,"utf16_col":0},"end":{"line_number":2776,"utf16_col":0}}},{"name":"Process and Thread","fully_qualified_name":"Process and Thread","kind":"section_4","ident_start":74476,"ident_end":74494,"extent_start":74471,"extent_end":76193,"ident_utf16":{"start":{"line_number":2250,"utf16_col":5},"end":{"line_number":2250,"utf16_col":23}},"extent_utf16":{"start":{"line_number":2250,"utf16_col":0},"end":{"line_number":2334,"utf16_col":0}}},{"name":"Example one","fully_qualified_name":"Example one","kind":"section_5","ident_start":74887,"ident_end":74898,"extent_start":74881,"extent_end":75497,"ident_utf16":{"start":{"line_number":2259,"utf16_col":6},"end":{"line_number":2259,"utf16_col":17}},"extent_utf16":{"start":{"line_number":2259,"utf16_col":0},"end":{"line_number":2296,"utf16_col":0}}},{"name":"Example two","fully_qualified_name":"Example two","kind":"section_5","ident_start":75503,"ident_end":75514,"extent_start":75497,"extent_end":76193,"ident_utf16":{"start":{"line_number":2296,"utf16_col":6},"end":{"line_number":2296,"utf16_col":17}},"extent_utf16":{"start":{"line_number":2296,"utf16_col":0},"end":{"line_number":2334,"utf16_col":0}}},{"name":"Send `SIGTERM` to Puma","fully_qualified_name":"Send `SIGTERM` to Puma","kind":"section_4","ident_start":76198,"ident_end":76220,"extent_start":76193,"extent_end":90433,"ident_utf16":{"start":{"line_number":2334,"utf16_col":5},"end":{"line_number":2334,"utf16_col":27}},"extent_utf16":{"start":{"line_number":2334,"utf16_col":0},"end":{"line_number":2776,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":168900469,"defaultBranch":"main","name":"leetcode-python-java","ownerLogin":"leetcode-python-java","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2019-02-03T02:13:43.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/204447696?v=4","public":true,"private":false,"isOrgOwned":true,"isArchived":false},"currentUser":null,"uploadToken":"-LI-wDMhIYl7um3b73ZLTkccDWLpE5Xl_R01ng_uxHy4Dp_rvw3JyJW1ezus6GHqAghLg3QdwFInkYiBLeVMFw","allShortcutsEnabled":false,"treeExpanded":true,"path":"README.md","symbolsExpanded":false,"refInfo":{"name":"master","listCacheKey":"v0:1742800255.0","canEdit":false,"currentOid":"9861d8e62f073d59c233e3f21f91751dd29df6c0"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"":{"items":[{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"}],"totalCount":2}},"fileTreeProcessingTime":42.156744,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"master","listCacheKey":"v0:1742800255.0","canEdit":false,"refType":"branch","currentOid":"9861d8e62f073d59c233e3f21f91751dd29df6c0","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"README.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/leetcode-python-java/leetcode-python-java/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"README.md","displayUrl":"https://github.com/leetcode-python-java/leetcode-python-java/blob/master/README.md?raw=true","headerInfo":{"blobSize":"88.3 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"8ab19ce","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fleetcode-python-java%2Fleetcode-python-java%2Fblob%2Fmaster%2FREADME.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"2776","truncatedSloc":"2355"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/leetcode-python-java/leetcode-python-java/blob/master/README.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/leetcode-python-java/leetcode-python-java/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/leetcode-python-java/leetcode-python-java/raw/refs/heads/master/README.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# Learn-Rails-by-Reading-Source-Code","[![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE)","[![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu)","## Table of Contents","","  * [Part 0: Before reading Rails 5 source code](#part-0-before-reading-rails-5-source-code)","      * [What will you learn from this tutorial?](#what-will-you-learn-from-this-tutorial)","  * [Part 1: Your app: an instance of YourProject::Application](#part-1-your-app-an-instance-of-yourprojectapplication)","  * [Part 2: config](#part-2-config)","  * [Part 3: Every request and response](#part-3-every-request-and-response)","      * [Puma](#puma)","      * [Rack apps](#rack-apps)","      * [The core app: ActionDispatch::Routing::RouteSet instance](#the-core-app-actiondispatchroutingrouteset-instance)","      * [Render view](#render-view)","      * [How can instance variables defined in Controller be accessed in view file?](#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file)","  * [Part 4: What does `$ rails server` do?](#part-4-what-does--rails-server-do)","      * [Thor](#thor)","      * [Rails::Server#start](#railsserverstart)","      * [Starting Puma](#starting-puma)","      * [Conclusion](#conclusion)","      * [Exiting Puma](#exiting-puma)","          * [Process and Thread](#process-and-thread)","          * [Send `SIGTERM` to Puma](#send-sigterm-to-puma)"," ","","## Part 0: Before reading Rails 5 source code","1) I suggest you to learn Rack [http://rack.github.io/](http://rack.github.io/) first. ","","In Rack, an object with `call` method is a Rack app.","","So what is the object with `call` method in Rails? I will answer this question in Part 1.","","2) You need a good IDE which can help for debugging. I use [RubyMine](https://www.jetbrains.com/).","","### What will you learn from this tutorial?","* How does Rails start your application?","","* How does Rails process every request?","","* How does Rails combine ActionController, ActionView and Routes together?","","* How does Puma, Rack, Rails work together?","","* What's Puma's multiple threads?","","I should start with the command `$ rails server`, but I put this to Part 4. Because it's a little bit complex.","","## Part 1: Your app: an instance of YourProject::Application","Assume your Rails app's class name is `YourProject::Application` (defined in `./config/application.rb`).","","First, I will give you a piece of important code.","```ruby","# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb","module Rails","  module Command","    class ServerCommand \u003c Base","      def perform","        # ...","        Rails::Server.new(server_options).tap do |server|","          # APP_PATH is '/path/to/your_project/config/application'.","          # require APP_PATH will create the 'Rails.application' object.","          # Actually, 'Rails.application' is an instance of `YourProject::Application`.","          # Rack server will start 'Rails.application'.","          require APP_PATH","          ","          Dir.chdir(Rails.application.root)","          ","          server.start","        end","      end","    end","  end","  ","  class Server \u003c ::Rack::Server","    def start","      #...","      # 'wrapped_app' will get an well prepared app from `./config.ru` file.","      # 'wrapped_app' will return an instance of `YourProject::Application`.","      # But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.","      # It has been created when `require APP_PATH` in previous code: ","      # in Rails::Command::ServerCommand#perform","      wrapped_app   ","","      super # Will invoke ::Rack::Server#start. ","    end","  end","end","```","A Rack server need to start with an `App` object. The `App` object should have a `call` method.","","`config.ru` is the conventional entry file for Rack app. So let's look at it.","```ruby","# ./config.ru","require_relative 'config/environment'","","run Rails.application # It seems that this is the app.","```","","Let's test it by `Rails.application.respond_to?(:call)`, it returns `true`.","","Let's step into `Rails.application`.","","```ruby","# ./gems/railties-5.2.2/lib/rails.rb","module Rails","  class \u003c\u003c self","    @application = @app_class = nil","","    attr_accessor :app_class","    ","    # Oh, 'application' is a class method for module 'Rails'. It is not an object.","    # But it returns an object which is an instance of 'app_class'.","    # So it is important for us to know what class 'app_class' is.","    def application","      @application ||= (app_class.instance if app_class)  ","    end","  end","end","```","","Because `Rails.application.respond_to?(:call)` returns `true`, `app_class.instance` has a `call` method.","","When was `app_class` set?","```ruby","module Rails","  class Application \u003c Engine","    class \u003c\u003c self","      def inherited(base) # This is a hooked method.","        Rails.app_class = base # This line set the 'app_class'.","      end","    end","  end","end","```","","`Rails::Application` is inherited by `YourProject`,","```ruby","# ./config/application.rb","module YourProject","  # The hooked method `inherited` will be invoked here.","  class Application \u003c Rails::Application","  end","end","```","So `YourProject::Application` is the `Rails.app_class` here.","","You may have a question: When does Rails execute the code in `./config/application.rb`?","","To answer this question, we need to look back to `config.ru`.","```ruby","# ./config.ru","require_relative 'config/environment' # Let's step into this line.","","run Rails.application # It seems that this is the app.","```","","```ruby","# ./config/environment.rb","# Load the Rails application.","require_relative 'application' # Let's step into this line.","","# Initialize the Rails application.","Rails.application.initialize!","```","","```ruby","# ./config/application.rb","require_relative 'boot'","","require 'rails/all'","","# Require the gems listed in Gemfile, including any gems","# you've limited to :test, :development, or :production.","Bundler.require(*Rails.groups)","","module YourProject","  # The hooked method `inherited` will be invoked here.","  class Application \u003c Rails::Application","    config.load_defaults 5.2","    config.i18n.default_locale = :zh","  end","end","```","Because `YourProject::Application` is `Rails.app_class`, `app_class.instance` is `YourProject::Application.instance`.","","But where is the `call` method? ","","`call` method should be a method of `YourProject::Application.instance`.","","The `call` method processes every request. Here it is.","```ruby","# ./gems/railties/lib/rails/engine.rb","module Rails","  class Engine \u003c Railtie","    def call(env) # This method will process every request. It is invoked by Rack. So it is very important. ","      req = build_request env","      app.call req.env # We will discuss the 'app' object later.","    end","  end","end","","# ./gems/railties/lib/rails/application.rb","module Rails","  class Application \u003c Engine","  end","end","","# ./config/application.rb","module YourProject","  class Application \u003c Rails::Application","  end","end","```","","Ancestor's chain is `YourProject::Application \u003c Rails::Application \u003c Rails::Engine \u003c Rails::Railtie`.","","So `YourProject::Application.new.respond_to?(:call)` returns `true`.","","But what does `app_class.instance` really do?","","`instance` is just a method name. What we really expects is something like `app_class.new`.","","Let's look at the definition of `instance`.","```ruby","# ./gems/railties/lib/rails/application.rb","module Rails","  class Application \u003c Engine","    def instance","      super.run_load_hooks! # This line confused me at the beginning. ","    end","  end","end","```","After a deep research, I realized that this code is equal to:","```ruby","def instance","  return_value = super # Keyword 'super' means call the ancestor's same name method: 'instance'.","  return_value.run_load_hooks!","end","```","","```ruby","# ./gems/railties/lib/rails/railtie.rb","module Rails","  class Railtie","    def instance","      # 'Rails::Railtie' is the top ancestor class.","      # Now 'app_class.instance' is 'YourProject::Application.new'.","      @instance ||= new","    end","  end","end","```","","```ruby","module Rails","  def application","    @application ||= (app_class.instance if app_class)","  end","end","```","","So `YourProject::Application.new` is `Rails.application`.","","Rack server will start `Rails.application` in the end.","","`Rails.application` is an important object in Rails.","","And you'll only have one `Rails.application` in one Puma process. ","","Multiple threads in a Puma process shares the `Rails.application`.","","## Part 2: config","The first time we see the `config` is in `./config/application.rb`.","```ruby","# ./config/application.rb","#...","module YourProject","  class Application \u003c Rails::Application","    # Actually, `config` is a method of `YourProject::Application`.","    # It is defined in it's grandfather's father: `Rails::Railtie`","    config.load_defaults 5.2  # Let's step into this line to see what is config.","    config.i18n.default_locale = :zh","  end","end","```","","```ruby","module Rails","  class Railtie","    class \u003c\u003c self","      # Method `:config` is defined here.","      # Actually, method `:config` is delegated to another object `:instance`.","      delegate :config, to: :instance ","      ","      # Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`","      def instance","        # return an instance of `YourProject::Application`.","        # Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`","        @instance ||= new ","      end","    end","  end","  ","  class Engine \u003c Railtie","  end","  ","  class Application \u003c Engine","    class \u003c\u003c self","      def instance","        # 'super' will call `:instance` method in `Railtie`, ","        # which will return an instance of `YourProject::Application`.","        return_value = super  ","        return_value.run_load_hooks!","      end","    end","    ","    def run_load_hooks!","      return self if @ran_load_hooks","      @ran_load_hooks = true","","      # ...","      self # `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.","    end","    ","    # This is the method `config`.","    def config","      # It is an instance of class `Rails::Application::Configuration`. ","      # Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   ","      @config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))","    end","  end","end","```","In the end, `YourProject::Application.config === Rails.application.config` returns `true`.","","Invoke Class's `config` method become invoke the class's instance's `config` method.","","```ruby","module Rails","  class \u003c\u003c self","    def configuration","      application.config","    end ","  end","end","```","So `Rails.configuration === Rails.application.config` returns `true`.","","FYI:","```ruby","module Rails","  class Application","    class Configuration \u003c ::Rails::Engine::Configuration","    end","  end","  ","  class Engine","    class Configuration \u003c ::Rails::Railtie::Configuration","      attr_accessor :middleware","","      def initialize(root = nil)","        super()","        #...","        @middleware = Rails::Configuration::MiddlewareStackProxy.new","      end","    end","  end","  ","  class Railtie","    class Configuration","    end","  end","end","```","","## Part 3: Every request and response","Imagine we have this route for the home page. ","```ruby","# ./config/routes.rb","Rails.application.routes.draw do","  root 'home#index' # HomeController#index","end","```","","### Puma","When a request is made from client, Puma will process the request in `Puma::Server#process_client`.","","If you want to know how Puma enter the method `Puma::Server#process_client`, please read part 4 or just search 'process_client' in this document.","","```ruby","# ./gems/puma-3.12.0/lib/puma/server.rb","require 'socket'","","module Puma","  # The HTTP Server itself. Serves out a single Rack app.","  #","  # This class is used by the `Puma::Single` and `Puma::Cluster` classes","  # to generate one or more `Puma::Server` instances capable of handling requests.","  # Each Puma process will contain one `Puma::Server` instacne.","  #","  # The `Puma::Server` instance pulls requests from the socket, adds them to a","  # `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.","  #","  # Each `Puma::Server` will have one reactor and one thread pool.","  class Server","    def initialize(app, events=Events.stdio, options={})","      # app: #\u003cPuma::Configuration::ConfigMiddleware:0x00007fcf1612c338 ","      #        @app = #\u003cYourProject::Application:0x00007fcf160fb120\u003e","      #        @config = #\u003cPuma::Configuration:0x00007fcf169a6c98\u003e         ","      #       \u003e","      @app = app","      #...","    end","    ","    # Given a connection on +client+, handle the incoming requests.","    #","    # This method support HTTP Keep-Alive so it may, depending on if the client","    # indicates that it supports keep alive, wait for another request before","    # returning.","    #","    def process_client(client, buffer)","      begin","        # ...","        while true","          # Let's step into this line.","          case handle_request(client, buffer) # Will return true in this example.","          when true","            return unless @queue_requests","            buffer.reset","","            ThreadPool.clean_thread_locals if clean_thread_locals","","            unless client.reset(@status == :run)","              close_socket = false","              client.set_timeout @persistent_timeout","              @reactor.add client","              return","            end","          end","        end","        # ...","      ensure","        buffer.reset","        client.close if close_socket","        #...","      end","    end","    ","    # Given the request +env+ from +client+ and a partial request body","    # in +body+, finish reading the body if there is one and invoke","    # the Rack app. Then construct the response and write it back to","    # +client+","    #","    def handle_request(req, lines)","      env = req.env","      # ... ","      # app: #\u003cPuma::Configuration::ConfigMiddleware:0x00007fcf1612c338 ","      #        @app = #\u003cYourProject::Application:0x00007fcf160fb120\u003e","      #        @config = #\u003cPuma::Configuration:0x00007fcf169a6c98\u003e         ","      #       \u003e","      status, headers, res_body = @app.call(env) # Let's step into this line.","","      # ...","      return keep_alive","    end    ","  end","end","```","```ruby","# ./gems/puma-3.12.0/lib/puma/configuration.rb","module Puma","  class Configuration","    class ConfigMiddleware","      def initialize(config, app)","        @config = config","        @app = app","      end","","      def call(env)","        env[Const::PUMA_CONFIG] = @config","        # @app: #\u003cYourProject::Application:0x00007fb4b1b4bcf8\u003e","        @app.call(env)","      end","    end","  end","end","```","","### Rack apps","As we see when Ruby enter `Puma::Configuration::ConfigMiddleware#call`, the `@app` is `YourProject::Application` instance.","","It is just the `Rails.application`.","","Rack need a `call` method to process request. ","","Rails defined this `call` method in `Rails::Engine#call`, so that `YourProject::Application` instance will have a `call` method.","","```ruby","# ./gems/railties/lib/rails/engine.rb","module Rails","  class Engine \u003c Railtie","    def call(env) # This method will process every request. It is invoked by Rack. ","      req = build_request env","      app.call req.env # The 'app' method is blow.","    end","    ","    def app","      # FYI,","      # caller: [","      # \"../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in \u003cmodule:Finisher\u003e'\", ","      # \"../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'\", ","      # \"../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'\", ","      # \"../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'\",","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'\", ","      # \"../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'\", ","      # \"../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'\", ","      # \"../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'\", ","      # \"/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `\u003ctop (required)\u003e'\", ","      # \"config.ru:2:in `require_relative'\", \"config.ru:2:in `block in \u003cmain\u003e'\", ","      # \"../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'\", ","      # \"../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'\", ","      # \"config.ru:in `new'\", \"config.ru:in `\u003cmain\u003e'\", ","      # \"../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'\", ","      # \"../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'\", ","      # \"../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'\", ","      # \"../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'\", ","      # \"../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'\", ","      # \"../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\",","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\",","      # \"../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\", ","      # \"../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\",","      # \"../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\", ","      # \"../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\",","      # \"../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\", ","      # \"../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u003ctop (required)\u003e'\", ","      # \"../path/to/your_project/bin/rails:5:in `require'\",","      # \"../path/to/your_project/bin/rails:5:in `\u003cmain\u003e'\"","      # ]","      puts \"caller: #{caller.inspect}\"","      ","      # You may want to know when is the @app first time initialized.","      # It is initialized when 'config.ru' is load by Rack server.","      # Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.","      # When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. ","      @app || @app_build_lock.synchronize { # '@app_build_lock = Mutex.new', so multiple threads share one '@app'.","        @app ||= begin","          # In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). ","          stack = default_middleware_stack # Let's step into this line","          # 'middleware' is a 'middleware_stack'!","          config.middleware = build_middleware.merge_into(stack)","          # FYI, this line is the last line and the result of this line is the return value for @app.","          config.middleware.build(endpoint) # look at this endpoint below. We will enter method `build` later.","        end","      }","      ","#  @app: #\u003cRack::Sendfile:0x00007ff14d905f60 ","#          @app=#\u003cActionDispatch::Static:0x00007ff14d906168 ","#                 @app=#\u003cActionDispatch::Executor:0x00007ff14d9061b8 ","#                        ...","#                           @app=#\u003cRack::ETag:0x00007fa1e540c4f8  ","#                                  @app=#\u003cRack::TempfileReaper:0x00007fa1e540c520 ","#                                         @app=#\u003cActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u003e","#                                 \u003e","#                         ...    ","#                        \u003e","#                             ","#                 \u003e","#         \u003e","      @app","    end","    ","    # Defaults to an ActionDispatch::Routing::RouteSet instance.","    def endpoint","      ActionDispatch::Routing::RouteSet.new_with_config(config)","    end","  end","end","```","","```ruby","# ./gems/railties/lib/rails/application...","module Rails","  class Application \u003c Engine","    def default_middleware_stack","      default_stack = DefaultMiddlewareStack.new(self, config, paths)","      default_stack.build_stack # Let's step into this line.","    end","    ","    class DefaultMiddlewareStack","      attr_reader :config, :paths, :app","","      def initialize(app, config, paths)","        @app = app","        @config = config","        @paths = paths","      end","","      def build_stack","        ActionDispatch::MiddlewareStack.new do |middleware|","          if config.force_ssl","            middleware.use ::ActionDispatch::SSL, config.ssl_options","          end","","          middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header","","          if config.public_file_server.enabled","            headers = config.public_file_server.headers || {}","","            middleware.use ::ActionDispatch::Static, paths[\"public\"].first, index: config.public_file_server.index_name, headers: headers","          end","","          if rack_cache = load_rack_cache","            require \"action_dispatch/http/rack_cache\"","            middleware.use ::Rack::Cache, rack_cache","          end","","          if config.allow_concurrency == false","            # User has explicitly opted out of concurrent request","            # handling: presumably their code is not threadsafe","","            middleware.use ::Rack::Lock","          end","","          middleware.use ::ActionDispatch::Executor, app.executor","","          middleware.use ::Rack::Runtime","          middleware.use ::Rack::MethodOverride unless config.api_only","          middleware.use ::ActionDispatch::RequestId","          middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies","","          middleware.use ::Rails::Rack::Logger, config.log_tags","          middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app","          middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format","","          unless config.cache_classes","            middleware.use ::ActionDispatch::Reloader, app.reloader","          end","","          middleware.use ::ActionDispatch::Callbacks","          middleware.use ::ActionDispatch::Cookies unless config.api_only","","          if !config.api_only \u0026\u0026 config.session_store","            if config.force_ssl \u0026\u0026 config.ssl_options.fetch(:secure_cookies, true) \u0026\u0026 !config.session_options.key?(:secure)","              config.session_options[:secure] = true","            end","            middleware.use config.session_store, config.session_options","            middleware.use ::ActionDispatch::Flash","          end","","          unless config.api_only","            middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware","          end","","          middleware.use ::Rack::Head","          middleware.use ::Rack::ConditionalGet","          middleware.use ::Rack::ETag, \"no-cache\"","","          middleware.use ::Rack::TempfileReaper unless config.api_only","        end","       end","     end","  end","end","```","```ruby","# ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb","module ActionDispatch","  class MiddlewareStack","    def use(klass, *args, \u0026block)","      middlewares.push(build_middleware(klass, args, block))","    end","    ","    def build_middleware(klass, args, block)","      Middleware.new(klass, args, block)","    end    ","    ","    def build(app = Proc.new)","      # See Enumerable#inject for more information.","      return_val = middlewares.freeze.reverse.inject(app) do |a, middleware|","        # a: app, and will be changed when iterating","        # middleware: #\u003cActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8\u003e, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating","        middleware.build(a) # Let's step into this line.","      end","","      return_val","    end    ","    ","    class Middleware","      def initialize(klass, args, block)","        @klass = klass","        @args  = args","        @block = block","      end","","      def build(app)","        # klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.","        # It's typical Rack app to use these middlewares.","        # See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. ","        klass.new(app, *args, \u0026block)","      end      ","    end","  end","end","```","### The core app: ActionDispatch::Routing::RouteSet instance","```ruby","# Paste again FYI. ","#  @app: #\u003cRack::Sendfile:0x00007ff14d905f60 ","#          @app=#\u003cActionDispatch::Static:0x00007ff14d906168 ","#                 @app=#\u003cActionDispatch::Executor:0x00007ff14d9061b8 ","#                        ...","#                           @app=#\u003cRack::ETag:0x00007fa1e540c4f8  ","#                                  @app=#\u003cRack::TempfileReaper:0x00007fa1e540c520 ","#                                         @app=#\u003cActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u003e","#                                 \u003e","#                         ...    ","#                        \u003e","#                             ","#                 \u003e","#         \u003e","``` ","As we see in the Rack middleware stack, the last @app is ","","`@app=#\u003cActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8\u003e`","```ruby","# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb","module ActionDispatch","  module Routing","    class RouteSet","      def initialize(config = DEFAULT_CONFIG)","        @set    = Journey::Routes.new","        @router = Journey::Router.new(@set)","      end","    ","      def call(env)","        req = make_request(env) # return ActionDispatch::Request.new(env)","        req.path_info = Journey::Router::Utils.normalize_path(req.path_info)","        @router.serve(req) # Let's step into this line.","      end","    end","  end","  ","# ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  ","  module Journey","    class Router","      class RoutingError \u003c ::StandardError","      end","    ","      attr_accessor :routes","        ","      def initialize(routes)","        @routes = routes","      end","        ","      def serve(req)","        find_routes(req).each do |match, parameters, route| # Let's step into 'find_routes'","          set_params  = req.path_parameters","          path_info   = req.path_info","          script_name = req.script_name","        ","          unless route.path.anchored","            req.script_name = (script_name.to_s + match.to_s).chomp(\"/\")","            req.path_info = match.post_match","            req.path_info = \"/\" + req.path_info unless req.path_info.start_with? \"/\"","          end","        ","          parameters = route.defaults.merge parameters.transform_values { |val|","            val.dup.force_encoding(::Encoding::UTF_8)","          }","        ","          req.path_parameters = set_params.merge parameters","        ","          # 'route' is an instance of ActionDispatch::Journey::Route. ","          # 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.","          status, headers, body = route.app.serve(req) # Let's step into method 'serve'","        ","          if \"pass\" == headers[\"X-Cascade\"]","            req.script_name     = script_name","            req.path_info       = path_info","            req.path_parameters = set_params","            next","          end","        ","          return [status, headers, body]","        end","    ","        [404, { \"X-Cascade\" =\u003e \"pass\" }, [\"Not Found\"]]","      end","      ","      def find_routes(req)","        routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|","          r.path.match(req.path_info)","        }","","        routes =","          if req.head?","            match_head_routes(routes, req)","          else","            match_routes(routes, req)","          end","","        routes.sort_by!(\u0026:precedence)","","        routes.map! { |r|","          match_data = r.path.match(req.path_info)","          path_parameters = {}","          match_data.names.zip(match_data.captures) { |name, val|","            path_parameters[name.to_sym] = Utils.unescape_uri(val) if val","          }","          [match_data, path_parameters, r]","        }","      end","","    end","  end","end","","# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb","module ActionDispatch","  module Routing","    class RouteSet","      class Dispatcher \u003c Routing::Endpoint","        def serve(req)","          params     = req.path_parameters # params: { action: 'index', controller: 'home' }","          controller = controller(req) # controller: HomeController","          # The definition of 'make_response!' is ","          # ActionDispatch::Response.create.tap { |res| res.request = request; }","          res        = controller.make_response!(req) ","          dispatch(controller, params[:action], req, res) # Let's step into this line.","        rescue ActionController::RoutingError","          if @raise_on_name_error","            raise","          else","            return [404, { \"X-Cascade\" =\u003e \"pass\" }, []]","          end","        end","        ","        private","        ","        def controller(req)","          req.controller_class","        rescue NameError =\u003e e","          raise ActionController::RoutingError, e.message, e.backtrace","        end","","        def dispatch(controller, action, req, res)","          controller.dispatch(action, req, res) # Let's step into this line.","        end","      end","    end","  end    ","end","","# ./gems/actionpack-5.2.2/lib/action_controller/metal.rb","module ActionController","  class Metal \u003c AbstractController::Base","    abstract!","    ","    def self.controller_name","      @controller_name ||= name.demodulize.sub(/Controller$/, \"\").underscore","    end","","    def self.make_response!(request)","      ActionDispatch::Response.new.tap do |res|","        res.request = request","      end","    end","    ","    class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new","    ","    def self.inherited(base)","      base.middleware_stack = middleware_stack.dup","      super","    end","    ","    # Direct dispatch to the controller. Instantiates the controller, then","    # executes the action named +name+.","    def self.dispatch(name, req, res)","      if middleware_stack.any?","        middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env","      else","        # 'self' is HomeController, so for this line Rails will new a HomeController instance.  ","        # Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.","        # These are some typical superclasses of HomeController. ","        # HomeController","        # \u003c ApplicationController","        # \u003c ActionController::Base","        # \u003c ActiveRecord::Railties::ControllerRuntime (module included)","        # \u003c ActionController::Instrumentation (module included)","        # \u003c ActionController::Rescue (module included)","        # \u003c AbstractController::Callbacks (module included)","        # \u003c ActionController::ImplicitRender (module included)","        # \u003c ActionController::BasicImplicitRender (module included)","        # \u003c ActionController::Renderers (module included) ","        # \u003c ActionController::Rendering (module included) ","        # \u003c ActionView::Layouts (module included) ","        # \u003c ActionView::Rendering (module included)","        # \u003c ActionDispatch::Routing::UrlFor (module included) ","        # \u003c AbstractController::Rendering (module included)","        # \u003c ActionController::Metal","        # \u003c AbstractController::Base","        new.dispatch(name, req, res) # Let's step into this line.","      end","    end","    ","    def dispatch(name, request, response)","      set_request!(request)","      set_response!(response)","      process(name) # Let's step into this line.","      request.commit_flash","      to_a","    end","    ","    def to_a","      response.to_a","    end","  end","end","","# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb","module AbstractController","  class Base","    def process(action, *args)","      @_action_name = action.to_s","","      unless action_name = _find_action_name(@_action_name)","        raise ActionNotFound, \"The action '#{action}' could not be found for #{self.class.name}\"","      end","","      @_response_body = nil","","      # action_name: 'index'","      process_action(action_name, *args) # Let's step into this line.","    end","  end","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb","module ActionController","  module Instrumentation","    def process_action(*args)","      raw_payload = {","        controller: self.class.name,","        action: action_name,","        params: request.filtered_parameters,","        headers: request.headers,","        format: request.format.ref,","        method: request.request_method,","        path: request.fullpath","      }","    ","      ActiveSupport::Notifications.instrument(\"start_processing.action_controller\", raw_payload.dup)","    ","      ActiveSupport::Notifications.instrument(\"process_action.action_controller\", raw_payload) do |payload|","        begin","          # self: #\u003cHomeController:0x00007fcd3c5dfd48\u003e","          result = super # Let's step into this line.","          payload[:status] = response.status","          result","        ensure","          append_info_to_payload(payload)","        end","      end","    end","  end","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb","module ActionController","  module Rescue","    def process_action(*args)","      super # Let's step into this line.","    rescue Exception =\u003e exception","      request.env[\"action_dispatch.show_detailed_exceptions\"] ||= show_detailed_exceptions?","      rescue_with_handler(exception) || raise","    end","  end  ","end","","# .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb","module AbstractController","  # = Abstract Controller Callbacks","  #","  # Abstract Controller provides hooks during the life cycle of a controller action.","  # Callbacks allow you to trigger logic during this cycle. Available callbacks are:","  #","  # * \u003ctt\u003eafter_action\u003c/tt\u003e","  # * \u003ctt\u003ebefore_action\u003c/tt\u003e","  # * \u003ctt\u003eskip_before_action\u003c/tt\u003e","  # * ...","  module Callbacks","    def process_action(*args)","      run_callbacks(:process_action) do","        # self: #\u003cHomeController:0x00007fcd3c5dfd48\u003e","        super # Let's step into this line.","      end","    end","  end","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb","module ActionController","  module Rendering","    def process_action(*)","      self.formats = request.formats.map(\u0026:ref).compact","      super # Let's step into this line.","    end","  end","end","","# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb","module AbstractController","  class Base","    def process_action(method_name, *args)","      # self: #\u003cHomeController:0x00007fcd3c5dfd48\u003e, method_name: 'index'","      # In the end, method 'send_action' is method 'send' by `alias send_action send` ","      send_action(method_name, *args)","    end","","    alias send_action send","  end","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb","module ActionController","  module BasicImplicitRender","    def send_action(method, *args)","      # self: #\u003cHomeController:0x00007fcd3c5dfd48\u003e, method_name: 'index'    ","      # Because 'send_action' is an alias of 'send',  ","      # self.send('index', *args) will goto HomeController#index.","      x = super","      # performed?: false (for this example)","      x.tap { default_render unless performed? } # Let's step into 'default_render' later.","    end","  end","end","","# ./your_project/app/controllers/home_controller.rb","class HomeController \u003c ApplicationController","  # Will go back to BasicImplicitRender#send_action when method 'index' is done.","  def index","    # Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?","    # I will answer this question later. ","    @users = User.all.pluck(:id, :name)","  end","end","```","","```html","# ./app/views/home/index.html.erb","\u003cdiv class=\"container\"\u003e","  \u003ch1 class=\"display-4 font-italic\"\u003e","    \u003c%= t('home.banner_title') %\u003e","    \u003c%= @users %\u003e","  \u003c/h1\u003e","\u003c/div\u003e","```","","### Render view","As we see in `ActionController::BasicImplicitRender::send_action`, the last line is `default_render`.","","So after `HomeController#index` is done, Ruby will execute method `default_render`.","","```ruby","# .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb ","module ActionController","  # Handles implicit rendering for a controller action that does not","  # explicitly respond with +render+, +respond_to+, +redirect+, or +head+.","  module ImplicitRender","    def default_render(*args)","      # Let's step into template_exists?","      if template_exists?(action_name.to_s, _prefixes, variants: request.variant)","        # Rails has found the default template './app/views/home/index.html.erb', so render it.","        render(*args) # Let's step into this line later","      #...","      else","        logger.info \"No template found for #{self.class.name}\\##{action_name}, rendering head :no_content\" if logger","        super","      end","    end","  end","end","","# .gems/actionview-5.2.2/lib/action_view/lookup_context.rb","module ActionView","  class LookupContext","    module ViewPaths","      # Rails checks whether the default template exists.","      def exists?(name, prefixes = [], partial = false, keys = [], **options)","        @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))","      end","      alias :template_exists? :exists?","    end","  end  ","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb","module ActionController","  module Instrumentation","    def render(*args)","      render_output = nil","      self.view_runtime = cleanup_view_runtime do","        Benchmark.ms {","          # self: #\u003cHomeController:0x00007fa7e9c54278\u003e ","          render_output = super # Let's step into super ","        }","      end","      render_output","    end","  end  ","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb","module ActionController","  module Rendering","    # Check for double render errors and set the content_type after rendering.","    def render(*args)","      raise ::AbstractController::DoubleRenderError if response_body","      super # Let's step into super","    end","  end","end","","# .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb","module AbstractController","  module Rendering","    # Normalizes arguments, options and then delegates render_to_body and","    # sticks the result in \u003ctt\u003eself.response_body\u003c/tt\u003e.","    def render(*args, \u0026block)","      options = _normalize_render(*args, \u0026block)","      ","      rendered_body = render_to_body(options) # Let's step into this line.","      ","      if options[:html]","        _set_html_content_type","      else","        _set_rendered_content_type rendered_format","      end","      ","      self.response_body = rendered_body","    end","  end","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb","module ActionController","  module Renderers","    def render_to_body(options)","      _render_to_body_with_renderer(options) || super # Let's step into this line and 'super' later.","    end","    ","    # For this example, this method return nil in the end.","    def _render_to_body_with_renderer(options)","      # The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`","      # '_renderers' is an instance predicate method. For more information, ","      # see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  ","      _renderers.each do |name|","        if options.key?(name)","          _process_options(options)","          method_name = Renderers._render_with_renderer_method_name(name)","          return send(method_name, options.delete(name), options)","        end","      end","      nil","    end","  end  ","end","","# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb","module ActionController","  module Rendering","    def render_to_body(options = {})","      super || _render_in_priorities(options) || \" \" # Let's step into 'super'","    end","  end","end","```","","```ruby","# .gems/actionview-5.2.2/lib/action_view/rendering.rb","module ActionView","  module Rendering","    def render_to_body(options = {})","      _process_options(options)","      ","      _render_template(options) # Let's step into this line.","    end","    ","    def _render_template(options)","      variant = options.delete(:variant)","      assigns = options.delete(:assigns)","      ","      context = view_context # We will step into this line later.","        ","      context.assign assigns if assigns","      lookup_context.rendered_format = nil if options[:formats]","      lookup_context.variants = variant if variant","        ","      view_renderer.render(context, options) # Let's step into this line.","    end","  end","end","","# .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb","module ActionView","  class Renderer","    def render(context, options)","      if options.key?(:partial)","        render_partial(context, options)","      else","        render_template(context, options) # Let's step into this line.","      end","    end","    ","    # Direct access to template rendering.","    def render_template(context, options)","      TemplateRenderer.new(@lookup_context).render(context, options) # Let's step into this line.","    end","  end","end","","# .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb","module ActionView","  class TemplateRenderer \u003c AbstractRenderer","    def render(context, options)","      @view    = context","      @details = extract_details(options)","      template = determine_template(options)","","      prepend_formats(template.formats)","","      @lookup_context.rendered_format ||= (template.formats.first || formats.first)","","      render_template(template, options[:layout], options[:locals]) # Let's step into this line.","    end","    ","    def render_template(template, layout_name = nil, locals = nil)","      view, locals = @view, locals || {}","","      render_with_layout(layout_name, locals) do |layout| # Let's step into this line","        instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do","          # template: #\u003cActionView::Template:0x00007f822759cbc0\u003e","          template.render(view, locals) { |*name| view._layout_for(*name) } # Let's step into this line","        end","      end","    end","    ","    def render_with_layout(path, locals)","      layout  = path \u0026\u0026 find_layout(path, locals.keys, [formats.first])","      content = yield(layout)","","      if layout","        view = @view","        view.view_flow.set(:layout, content)","        layout.render(view, locals) { |*name| view._layout_for(*name) }","      else","        content","      end","    end","  end","end","","# .gems/actionview-5.2.2/lib/action_view/template.rb","module ActionView","  class Template","    def render(view, locals, buffer = nil, \u0026block)","      instrument_render_template do","        # self: #\u003cActionView::Template:0x00007f89bab1efb8 ","        #           @identifier=\"/path/to/your/project/app/views/home/index.html.erb\" ","        #           @source=\"\u003cdiv class='container'\\n ...\"","        #        \u003e","        compile!(view)","        # method_name: \"_app_views_home_index_html_erb___3699380246341444633_70336654511160\" (This method is defined in 'def compile(mod)' below)","        # view: #\u003c#\u003cClass:0x00007ff10d6c9d18\u003e:0x00007ff10ea050a8\u003e, view is an instance of \u003ca subclass of ActionView::Base\u003e which has same instance variables defined in the instance of HomeController.","        # You will get the result html after invoking 'view.send'. ","        view.send(method_name, locals, buffer, \u0026block)","      end","    rescue =\u003e e","      handle_render_error(view, e)","    end","    ","    # Compile a template. This method ensures a template is compiled","    # just once and removes the source after it is compiled.","    def compile!(view)","      return if @compiled","","      # Templates can be used concurrently in threaded environments","      # so compilation and any instance variable modification must","      # be synchronized","      @compile_mutex.synchronize do","        # Any thread holding this lock will be compiling the template needed","        # by the threads waiting. So re-check the @compiled flag to avoid","        # re-compilation","        return if @compiled","","        if view.is_a?(ActionView::CompiledTemplates)","          mod = ActionView::CompiledTemplates","        else","          mod = view.singleton_class","        end","","        instrument(\"!compile_template\") do","          compile(mod) # Let's step into this line.","        end","","        # Just discard the source if we have a virtual path. This","        # means we can get the template back.","        @source = nil if @virtual_path","        @compiled = true","      end","    end","    ","    def compile(mod)","      encode!","      # @handler: #\u003cActionView::Template::Handlers::ERB:0x00007ff10e1be188\u003e","      code = @handler.call(self) # Let's step into this line.","","      # Make sure that the resulting String to be eval'd is in the","      # encoding of the code","      source = \u003c\u003c-end_src.dup","        def #{method_name}(local_assigns, output_buffer)","          _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}","        ensure","          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer","        end","      end_src","","      # ...","","      #  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)","      #              _old_virtual_path, @virtual_path = @virtual_path, \"home/index\";_old_output_buffer = @output_buffer;;","      #              @output_buffer = output_buffer || ActionView::OutputBuffer.new;","      #              @output_buffer.safe_append='\u003cdiv class=\"container\"\u003e","      #                \u003ch1 class=\"display-4 font-italic\"\u003e","      #                  '.freeze;","      #                   @output_buffer.append=( t('home.banner_title') );","      #                   @output_buffer.append=( @users ); ","      #                   @output_buffer.safe_append='","      #                \u003c/h1\u003e","      #              \u003c/div\u003e","      #              '.freeze;","      #              @output_buffer.to_s","      #            ensure","      #              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer","      #            end","      mod.module_eval(source, identifier, 0) # This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'","      # mod: ActionView::CompiledTemplates","      ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])","    end","","# .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     ","    module Handlers","      class ERB","        def call(template)","          template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)","","          erb = template_source.gsub(ENCODING_TAG, \"\")","          encoding = $2","","          erb.force_encoding valid_encoding(template.source.dup, encoding)","","          # Always make sure we return a String in the default_internal","          erb.encode!","","          self.class.erb_implementation.new(","            erb,","            escape: (self.class.escape_whitelist.include? template.type),","            trim: (self.class.erb_trim_mode == \"-\")","          ).src","        end","      end","    end","  end","end","```","","### How can instance variables defined in Controller be accessed in view file?","It's time to answer the question before: ","","How can instance variables like `@users` defined in `HomeController` be accessed in `./app/views/home/index.html.erb`?","","I will answer this question by showing the source code below.","```ruby","# ./gems/actionview-5.2.2/lib/action_view/rendering.rb","module ActionView","  module Rendering","    def view_context","      # view_context_class is a subclass of ActionView::Base.","      view_context_class.new( # Let's step into this line later.","        view_renderer,","        view_assigns, # This line will set the instance variables like '@users' in this example. Let's step into this line.  ","        self","      )","    end","    ","    def view_assigns","      # self: #\u003cHomeController:0x00007f83ecfed310\u003e","      protected_vars = _protected_ivars","      # instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  ","      variables      = instance_variables ","","      variables.reject! { |s| protected_vars.include? s }","      ret = variables.each_with_object({}) { |name, hash|","        hash[name.slice(1, name.length)] = instance_variable_get(name)","      }","      ","      # ret: {\"marked_for_same_origin_verification\"=\u003etrue, \"users\"=\u003e[[1, \"Lane\"], [2, \"John\"], [4, \"Frank\"]]}","      ret","    end","    ","    def view_context_class","      # Will return a subclass of ActionView::Base.","      @_view_context_class ||= self.class.view_context_class","    end","    ","    # How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb","    # FYI, the method 'append_features' will be executed automatically before method 'included' executed. ","    # https://apidock.com/ruby/v1_9_3_392/Module/append_features  ","    module ClassMethods","      def view_context_class","        # self: HomeController","        @view_context_class ||= begin","          supports_path = supports_path?","          routes  = respond_to?(:_routes)  \u0026\u0026 _routes","          helpers = respond_to?(:_helpers) \u0026\u0026 _helpers","","          Class.new(ActionView::Base) do","            if routes","              include routes.url_helpers(supports_path)","              include routes.mounted_helpers","            end","","            if helpers","              include helpers","            end","          end","        end","      end","    end","  end","end","","# ./gems/actionview-5.2.2/lib/action_view/base.rb","module ActionView","  class Base","    def initialize(context = nil, assigns = {}, controller = nil, formats = nil)","      @_config = ActiveSupport::InheritableOptions.new","","      if context.is_a?(ActionView::Renderer)","        @view_renderer = context","      else","        lookup_context = context.is_a?(ActionView::LookupContext) ?","          context : ActionView::LookupContext.new(context)","        lookup_context.formats  = formats if formats","        lookup_context.prefixes = controller._prefixes if controller","        @view_renderer = ActionView::Renderer.new(lookup_context)","      end","","      @cache_hit = {}","      ","      assign(assigns) # Let's step into this line.","      ","      assign_controller(controller)","      _prepare_context","    end","    ","    def assign(new_assigns)","      @_assigns = ","        new_assigns.each do |key, value|","          # This line will set the instance variables (like '@users') in HomeController to itself.","          instance_variable_set(\"@#{key}\", value)","        end","    end","  end","end","","```","After all Rack apps called, user will get the response.  ","","## Part 4: What does `$ rails server` do?","","If you start Rails by `$ rails server`. You may want to know what does this command do? ","","The command `rails` locates at `./bin/`.","```ruby","#!/usr/bin/env ruby","APP_PATH = File.expand_path('../config/application', __dir__)","","require_relative '../config/boot'","require 'rails/commands' # Let's look at this file.","```  ","","```ruby","# ./railties-5.2.2/lib/rails/commands.rb","require \"rails/command\"","","aliases = {","  \"g\"  =\u003e \"generate\",","  \"d\"  =\u003e \"destroy\",","  \"c\"  =\u003e \"console\",","  \"s\"  =\u003e \"server\",","  \"db\" =\u003e \"dbconsole\",","  \"r\"  =\u003e \"runner\",","  \"t\"  =\u003e \"test\"","}","","command = ARGV.shift","command = aliases[command] || command # command is 'server'","","Rails::Command.invoke command, ARGV # Let's step into this line.","```","","```ruby","# ./railties-5.2.2/lib/rails/command.rb","module Rails","  module Command","    class \u003c\u003c self","      def invoke(full_namespace, args = [], **config)","        # ...","        # command_name: 'server'  ","        # After calling `find_by_namespace`, we will get this result:","        # command: Rails::Command::ServerCommand","        command = find_by_namespace(namespace, command_name)","        ","        # Equals to: Rails::Command::ServerCommand.perform('server', args, config)","        command.perform(command_name, args, config)","      end","    end","  end","end","```","","```ruby","# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb","module Rails ","  module Command","    # There is a class method 'perform' in the Base class.","    class ServerCommand \u003c Base","    end","  end","end","```","","### Thor","Thor is a toolkit for building powerful command-line interfaces.","","[https://github.com/erikhuda/thor](https://github.com/erikhuda/thor)","","Inheritance relationship: `Rails::Command::ServerCommand \u003c Rails::Command::Base \u003c Thor`","","```ruby","# ./gems/railties-5.2.2/lib/rails/command/base.rb","module Rails","  module Command","    class Base \u003c Thor","      class \u003c\u003c self","        # command: 'server'","        def perform(command, args, config)","          #...","          dispatch(command, args.dup, nil, config) # Thor.dispatch","        end","      end","    end","  end","end","```","","```ruby","# ./gems/thor-0.20.3/lib/thor.rb","class Thor","  class \u003c\u003c self","    # meth is 'server'","    def dispatch(meth, given_args, given_opts, config)","      # ...","      # Will new a Rails::Command::ServerCommand instance here ","      # because 'self' is Rails::Command::ServerCommand.","      instance = new(args, opts, config)","      # ...","      # Method 'invoke_command' is defined in Thor::Invocation. ","      # command: {Thor::Command}#\u003cstruct Thor::Command name=\"server\" ...\u003e ","      instance.invoke_command(command, trailing || [])","    end","  end","end","","# ./gems/thor-0.20.3/lib/thor/invocation.rb","class Thor","  # FYI, this module is included in Thor.","  # And Thor is grandfather of Rails::Command::ServerCommand","  module Invocation","    def invoke_command(command, *args) # 'invoke_command' is defined at here.","      # ...","      # self: #\u003cRails::Command::ServerCommand:0x00007fdcc49791b0\u003e ","      # command: {Thor::Command}#\u003cstruct Thor::Command name=\"server\" ...\u003e ","      command.run(self, *args)","    end","  end","end","","# ./gems/thor-0.20.3/lib/thor/command.rb","class Thor","  class Command \u003c Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)","    def run(instance, args = [])","      # ...","      # instance: #\u003cRails::Command::ServerCommand:0x00007fdcc49791b0\u003e","      # name: \"server\"","      # This line will invoke Rails::Command::ServerCommand#server, ","      # the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.","      # I will show you how the instance method 'server' is implicitly defined. ","      instance.__send__(name, *args) ","    end  ","  end","end","```","","```ruby","# ./gems/thor-0.20.3/lib/thor.rb","class Thor","  # ...","  include Thor::Base # Will invoke hooked method 'Thor::Base.included(self)'","end","","# ./gems/thor-0.20.3/lib/thor/base.rb","module Thor","  module Base","    class \u003c\u003c self","      # 'included' is a hooked method.","      # When module 'Thor::Base' is included, method 'included' is executed. ","      def included(base) ","        # base: Thor","        # this line will define `Thor.method_added`.  ","        base.extend ClassMethods","        # Module 'Invocation' is included for class 'Thor' here. ","        # Because Thor is grandfather of Rails::Command::ServerCommand,","        # 'invoke_command' will be instance method of Rails::Command::ServerCommand       ","        base.send :include, Invocation # 'invoke_command' is defined in module Invocation","        base.send :include, Shell","      end","    end","    ","    module ClassMethods","      # 'method_added' is a hooked method.","      # When an instance method is created in Rails::Command::ServerCommand, ","      # `method_added` will be executed.","      # So, when method `perform` is defined in Rails::Command::ServerCommand,","      # `method_added` will be executed and create_command('perform') will be invoked. ","      # So in the end, method 'server' will be created by alias_method('server', 'perform').","      # And the method 'server' is for the 'server' in command `$ rails server`.","      def method_added(meth)","        # ...","        # self: {Class} Rails::Command::ServerCommand ","        create_command(meth) # meth is 'perform'. Let's step into this line.","      end","    end","  end","end","","# ./gems/railties-5.2.2/lib/rails/command/base.rb","module Rails","  module Command","    # Rails::Command::Base is superclass of Rails::Command::ServerCommand","    module Base","      class \u003c\u003c self","        def create_command(meth)","          if meth == \"perform\"","            # Calling instance method 'server' of Rails::Command::ServerCommand ","            # will be transferred to call instance method 'perform'.","            alias_method('server', meth) ","          end","        end  ","      end","    end","  end","end","","# ./gems/thor-0.20.3/lib/thor/command.rb","class Thor","  class Command \u003c Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)","    def run(instance, args = [])","      #...","      # instance: {Rails::Command::ServerCommand}#\u003cRails::Command::ServerCommand:0x00007fa5f319bf40\u003e","      # name: 'server'.","      # Will actually invoke 'instance.perform(*args)'. ","      # Equals to invoke Rails::Command::ServerCommand#perform(*args).","      # Let's step into  Rails::Command::ServerCommand#perform.","      instance.__send__(name, *args) ","    end","  end","end","","# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb","module Rails","  module Command","    class ServerCommand \u003c Base","      # This is the method will be executed when `$ rails server`.","      def perform","        # ...","        Rails::Server.new(server_options).tap do |server|","          # APP_PATH is '/path/to/your_project/config/application'.","          # require APP_PATH will create the 'Rails.application' object.","          # 'Rails.application' is 'YourProject::Application.new'.","          # Rack server will start 'Rails.application'.","          require APP_PATH","          ","          Dir.chdir(Rails.application.root)","          ","          server.start # Let's step into this line.","        end","      end","    end","  end","end","```","","### Rails::Server#start","```ruby","# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb","module Rails","  class Server \u003c ::Rack::Server","    def start","      print_boot_information","      ","      trap(:INT) do","        exit","      end","      ","      create_tmp_directories","      setup_dev_caching","      ","      # This line is important. Although the method name seems not.","      log_to_stdout# Let step into this line.","","      super # Will invoke ::Rack::Server#start. I will show you later. ","    ensure","      puts \"Exiting\" unless @options \u0026\u0026 options[:daemonize]","    end","    ","    def log_to_stdout","      # 'wrapped_app' will get an well prepared Rack app from './config.ru' file.","      # It's the first time invoke 'wrapped_app'.","      # The app is an instance of YourProject::Application.","      # But the app is not created in 'wrapped_app'.","      # It has been created when `require APP_PATH` in previous code,","      # just at the 'perform' method in Rails::Command::ServerCommand.   ","      wrapped_app # Let's step into this line","","      # ...","    end","  end","end","","# ./gems/rack-2.0.6/lib/rack/server.rb","module Rack","  class Server","    def wrapped_app","      @wrapped_app ||= ","        build_app(","          app # Let's step into this line.","        )","    end","    ","    def app","      @app ||= build_app_and_options_from_config # Let's step into this line.","      @app","    end","    ","    def build_app_and_options_from_config","      # ...","      # self.options[:config]: 'config.ru'. Let's step into this line.","      app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)","      # ...","      app","    end","    ","    # This method is called in Rails::Server#start","    def start(\u0026blk)","      #...","      wrapped_app","      #...","","      # server: {Module} Rack::Handler::Puma","      # wrapped_app: {YourProject::Application} #\u003cYourProject::Application:0x00007f7fe5523f98\u003e","      server.run(wrapped_app, options, \u0026blk) # We will step into this line (Rack::Handler::Puma.run) later.","    end","  end","end","","# ./gems/rack/lib/rack/builder.rb","module Rack","  module Builder","    def self.parse_file(config, opts = Server::Options.new)","      # config: 'config.ru'","      cfgfile = ::File.read(config)","      ","      app = new_from_string(cfgfile, config)","      ","      return app, options","    end","  ","    # Let's guess what does 'run Rails.application' do in config.ru?","    # You may guess that: ","    #   Run YourProject::Application instance.","    # But 'run' maybe not what you are thinking about.","    # Because the 'self' object in 'config.ru' is #\u003cRack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]\u003e, ","    # 'run' is an instance method of Rack::Builder.","    # Let's look at the definition of the 'run' method: ","    # def run(app)","    #   @run = app # Just set an instance variable for Rack::Builder instance.","    # end","    def self.new_from_string(builder_script, file=\"(rackup)\")","      # Rack::Builder implements a small DSL to iteratively construct Rack applications.","      eval \"Rack::Builder.new {\\n\" + builder_script + \"\\n}.to_app\",","        TOPLEVEL_BINDING, file, 0","    end","  end","end","```","","### Starting Puma","As we see in `Rack::Server#start`, there is `Rack::Handler::Puma.run(wrapped_app, options, \u0026blk)`.","","```ruby","# ./gems/puma-3.12.0/lib/rack/handler/puma.rb","module Rack","  module Handler","    module Puma","      # This method is invoked in `Rack::Server#start`:","      # Rack::Handler::Puma.run(wrapped_app, options, \u0026blk) ","      def self.run(app, options = {})","        conf   = self.config(app, options)","","        # ...","        launcher = ::Puma::Launcher.new(conf, :events =\u003e events)","","        begin","          # Puma will run your app (instance of YourProject::Application)","          launcher.run # Let's step into this line.","        rescue Interrupt ","          puts \"* Gracefully stopping, waiting for requests to finish\"","          launcher.stop","          puts \"* Goodbye!\"","        end","      end","    end  ","  end","end","","# .gems/puma-3.12.0/lib/puma/launcher.rb","module Puma","  # Puma::Launcher is the single entry point for starting a Puma server based on user","  # configuration. It is responsible for taking user supplied arguments and resolving them","  # with configuration in `config/puma.rb` or `config/puma/\u003cenv\u003e.rb`.","  #","  # It is responsible for either launching a cluster of Puma workers or a single","  # Puma server.","  class Launcher","    def initialize(conf, launcher_args={})","      @runner        = nil","      @config        = conf","","      # ...","      if clustered?","        # ...","        @runner = Cluster.new(self, @events)","      else","        # For this example, it is Single.new.","        @runner = Single.new(self, @events)","      end","      ","      # ...","    end","        ","    def run","      #...","","      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. ","      setup_signals # We will discuss this line later.","      ","      set_process_title","      ","      @runner.run # We will enter `Single.new(self, @events).run` here.","","      case @status","      when :halt","        log \"* Stopping immediately!\"","      when :run, :stop","        graceful_stop","      when :restart","        log \"* Restarting...\"","        ENV.replace(previous_env)","        @runner.before_restart","        restart!","      when :exit","        # nothing","      end","    end","  end","end","```","","```ruby","# .gems/puma-3.12.0/lib/puma/single.rb","module Puma","  # This class is instantiated by the `Puma::Launcher` and used","  # to boot and serve a Ruby application when no puma \"workers\" are needed","  # i.e. only using \"threaded\" mode. For example `$ puma -t 1:5`","  #","  # At the core of this class is running an instance of `Puma::Server` which","  # gets created via the `start_server` method from the `Puma::Runner` class","  # that this inherits from.","  class Single \u003c Runner","    def run","      # ...","","      # @server: Puma::Server.new(app, @launcher.events, @options)","      @server = server = start_server # Let's step into this line.","","      # ...","      thread = server.run # Let's step into this line later.","      ","      # This line will suspend the main thread execution.","      # And the `thread`'s block (which is method `handle_servers`) will be executed.","      # See `Thread#join` for more information.","      # I will show you a simple example for using `thread.join`.","      # Please search `test_thread_join.rb` in this document.","      thread.join","      ","      # The below line will never be executed because `thread` is always running and `thread` has joined.","      # When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed","      # because the block of `Signal.trap \"SIGTERM\"` in `Puma::Launcher#setup_signals` will be executed.","      # If you remove the line `thread.join`, the below line will be executed, ","      # but the main thread will exit after all code executed and all the threads not joined will be killed.","      puts \"anything which will never be executed...\"","    end","  end","end","```","```ruby","# .gems/puma-3.12.0/lib/puma/runner.rb","module Puma","  # Generic class that is used by `Puma::Cluster` and `Puma::Single` to","  # serve requests. This class spawns a new instance of `Puma::Server` via","  # a call to `start_server`.","  class Runner","    def app","      @app ||= @launcher.config.app","    end","    ","    def start_server","      min_t = @options[:min_threads]","      max_t = @options[:max_threads]","","      server = Puma::Server.new(app, @launcher.events, @options)","      server.min_threads = min_t","      server.max_threads = max_t","      # ...","","      server","    end","  end","end","```","","```ruby","# .gems/puma-3.12.0/lib/puma/server.rb","module Puma","  class Server","    def run(background=true)","      #...","      @status = :run","      queue_requests = @queue_requests","","      # This part is important.","      # Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.","      # And the block will process the request by calling method `process_client`.","      # Let's step into this line later to see how Puma call the block.","      @thread_pool = ThreadPool.new(@min_threads,","                                    @max_threads,","                                    IOBuffer) do |client, buffer|","","        # Advertise this server into the thread","        Thread.current[ThreadLocalKey] = self","","        process_now = false","","        if queue_requests","          process_now = client.eagerly_finish","        end  ","        ","        # ...","        if process_now","          # Process the request. You can look upon `client` as request.","          # If you want to know more about 'process_client', please read part 3 ","          # or search 'process_client' in this document.  ","          process_client(client, buffer)  ","        else","          client.set_timeout @first_data_timeout","          @reactor.add client","        end","      end","      ","      # ...","","      if background # background: true (for this example)","        # This part is important.","        # Remember Puma created a thread here!","        # We will know that the newly created thread's job is waiting for requests.","        # When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.","        # The method `handle_servers` in thread's block will be executed immediately ","        # (executed in the newly created thread, not in the main thread).","        @thread = Thread.new { handle_servers } # Let's step into this line to see what I said.","        return @thread","      else","        handle_servers","      end","    end","    ","    def handle_servers      ","      sockets = [check] + @binder.ios","      pool = @thread_pool","      queue_requests = @queue_requests","","      # ...","      ","      # The thread is always running, because @status has been set to :run in Puma::Server#run.","      # Yes, it should always be running to transfer the incoming requests.","      while @status == :run","        begin","          # This line will cause current thread waiting until a request arrives.","          # So it will be the entry of every request!","          # sockets: [#\u003cIO:fd 23\u003e, #\u003cTCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u003e] ","          ios = IO.select sockets","        ","          ios.first.each do |sock|","            if sock == check","              break if handle_check","            else","              if io = sock.accept_nonblock","                # You can simply look upon a Puma::Client instance as a request.  ","                client = Client.new(io, @binder.env(sock))","                ","                # ...","                ","                # FYI, the method '\u003c\u003c' is redefined.","                # Add the request (client) to thread pool means ","                # a thread in the pool will process this request (client).   ","                pool \u003c\u003c client # Let's step into this line.","                ","                pool.wait_until_not_full # Let's step into this line later.","              end","            end","          end","        rescue Object =\u003e e","          @events.unknown_error self, e, \"Listen loop\"","        end","      end","    end    ","  end","end","```","","```ruby","# .gems/puma-3.12.0/lib/puma/thread_pool.rb","module Puma","  class ThreadPool","    # Maintain a minimum of +min+ and maximum of +max+ threads","    # in the pool.","    #","    # The block passed is the work that will be performed in each","    # thread.","    #","    def initialize(min, max, *extra, \u0026block)","      #..","      @mutex = Mutex.new","      @todo = [] # @todo is requests (in Puma, they are Puma::Client instances) which need to be processed.  ","      @spawned = 0 # the count of @spawned threads","      @min = Integer(min) # @min threads count","      @max = Integer(max) # @max threads count","      @block = block # block will be called in method `spawn_thread` to processed a request.    ","      @workers = []","      @reaper = nil","","      @mutex.synchronize do","        @min.times { spawn_thread } # Puma spawns @min count threads.","      end","    end","    ","    def spawn_thread","      @spawned += 1","","      # Create a new Thread now.","      # The block of the thread will be executed immediately and separately from the calling thread (main thread).","      th = Thread.new(@spawned) do |spawned|","        # Thread name is new in Ruby 2.3","        Thread.current.name = 'puma %03i' % spawned if Thread.current.respond_to?(:name=)","        block = @block","        mutex = @mutex","        #...","","        extra = @extra.map { |i| i.new }","","        # Pay attention to here: ","        # 'while true' means this part will always be running.","        # And there will be @min count threads always running!","        # Puma uses these threads to process requests. ","        # The line: 'not_empty.wait(mutex)' will make current thread waiting.  ","        while true","          work = nil","","          continue = true","","          mutex.synchronize do","            while todo.empty?","              if @trim_requested \u003e 0","                @trim_requested -= 1","                continue = false","                not_full.signal","                break","              end","","              if @shutdown","                continue = false","                break","              end","","              @waiting += 1 # `@waiting` is the waiting threads count.","              not_full.signal","              ","              # This line will cause current thread waiting","              # until `not_empty.signal` executed in some other place to wake it up .","              # Actually, `not_empty.signal` is located at `def \u003c\u003c(work)` in the same file.","              # You can search `def \u003c\u003c(work)` in this document.","              # Method `\u003c\u003c` is used in method `handle_servers`: `pool \u003c\u003c client` in Puma::Server#run.","              # `pool \u003c\u003c client` means add a request to the thread pool, ","              # and then the waked up thread will process the request. ","              not_empty.wait mutex","              ","              @waiting -= 1","            end","","            # `work` is the request (in Puma, it's Puma::Client instance) which need to be processed.","            work = todo.shift if continue  ","          end","","          break unless continue","","          if @clean_thread_locals","            ThreadPool.clean_thread_locals","          end","","          begin","            # `block.call` will switch program to the block definition part.","            # The block definition part is in `Puma::Server#run`:","            # @thread_pool = ThreadPool.new(@min_threads,","            #                               @max_threads,","            #                               IOBuffer) do |client, buffer| #...; end","            # So please search `ThreadPool.new` in this document to look back.","            block.call(work, *extra)","          rescue Exception =\u003e e","            STDERR.puts \"Error reached top of thread-pool: #{e.message} (#{e.class})\"","          end","        end","","        mutex.synchronize do","          @spawned -= 1","          @workers.delete th","        end","      end # end of the Thread.new.","","      @workers \u003c\u003c th","","      th","    end","    ","    def wait_until_not_full","      @mutex.synchronize do","        while true","          return if @shutdown","","          # If we can still spin up new threads and there","          # is work queued that cannot be handled by waiting","          # threads, then accept more work until we would","          # spin up the max number of threads.","          return if @todo.size - @waiting \u003c @max - @spawned","","          @not_full.wait @mutex ","        end","      end","    end","    ","    # Add +work+ to the todo list for a Thread to pickup and process.","    def \u003c\u003c(work)","      @mutex.synchronize do","        if @shutdown","          raise \"Unable to add work while shutting down\"","        end","        ","        # work: #\u003cPuma::Client:0x00007ff114ece6b0\u003e","        # You can look upon Puma::Client instance as a request.","        @todo \u003c\u003c work","","        if @waiting \u003c @todo.size and @spawned \u003c @max","          spawn_thread # Create one more thread to process request. ","        end","","        # Wake up the waiting thread to process the request.","        # The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.","        # This code is in `spawn_thread`:","        # while true ","        #   # ...","        #   not_empty.wait mutex","        #   # ... ","        #   block.call(work, *extra) # This line will process the request.","        # end ","        @not_empty.signal  ","      end","    end","  end","end","```","","### Conclusion","In conclusion, `$ rails server` will execute `Rails::Command::ServerCommand#perform`. ","","In `#perform`, call `Rails::Server#start`. Then call `Rack::Server#start`.","","Then call `Rack::Handler::Puma.run(YourProject::Application.new)`.","","In `.run`, Puma will new a always running Thread for `ios = IO.select(#\u003cTCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u003e)`.","","Request is created from `ios` object.","","A thread in Puma threadPool will process the request.","","The thread will invoke Rack apps' `call` to get the response for the request.","","### Exiting Puma","#### Process and Thread","Because Puma is using multiple threads, we need to have some basic concepts about Process and Thread.","","This link is good for you to obtain the concepts: [Process and Thread](https://stackoverflow.com/questions/4894609/will-a-cpu-process-have-at-least-one-thread)  ","","In the next part, you will often see `thread.join`.","","I will use two simple example to tell what does `thread.join` do.","","##### Example one","Try to run `test_thread_join.rb`. ","","```ruby","# ./test_thread_join.rb","thread = Thread.new() do","  3.times do |n|","    puts \"~~~~ \" + n.to_s","  end","end","","# sleep 1","puts \"==== I am the main thread.\"","","# thread.join # Try to uncomment these two lines to see the differences.","# puts \"==== after thread.join\"","```","You will find that if there is no `thread.join`, you can see ","```log","==== I am the main thread.","==== after thread.join","~~~~ 0","~~~~ 1","~~~~ 2","```","in console.","","After you added `thread.join`, you can see:","```log","==== I am the main thread.","~~~~ 0","~~~~ 1","~~~~ 2","==== after thread.join","````","in console.","","##### Example two","Try to run `test_thread_join2.rb`. ","```ruby","# ./test_thread_join2.rb","arr = [","  Thread.new do","    puts 'I am arr[0]'","    sleep 1","    puts 'After arr[0]'","  end,","  Thread.new do","    puts 'I am arr[1]'","    sleep 5","    puts 'After arr[1]'","  end,","  Thread.new do","    puts 'I am arr[2]'","    sleep 8","    puts 'After arr[2]'","  end","]","","puts \"Thread.list.size:  #{Thread.list.size}\" # returns 4 (including the main thread)","","sleep 2","","arr.each { |thread| puts \"~~~~~ #{thread}\" }","","puts \"Thread.list.size:  #{Thread.list.size}\" # returns 3 (because arr[0] is dead)","","arr[1].join # uncomment to see differences","","arr.each { |thread| puts \"~~~~~ #{thread}\" }","","sleep 7","puts \"Exit main thread\"","```","","#### Send `SIGTERM` to Puma","When you stop Puma by running `$ kill -s SIGTERM puma_process_id`, you will enter `setup_signals` in `Puma::Launcher#run`.","```ruby","# .gems/puma-3.12.0/lib/puma/launcher.rb","module Puma","  # Puma::Launcher is the single entry point for starting a Puma server based on user","  # configuration.","  class Launcher","    def run","      #...","","      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. ","      setup_signals # Let's step into this line.","      ","      set_process_title","      ","      @runner.run","","      # ...","    end","    ","    # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.","    # Signal.list #=\u003e {\"EXIT\"=\u003e0, \"HUP\"=\u003e1, \"INT\"=\u003e2, \"QUIT\"=\u003e3, \"ILL\"=\u003e4, \"TRAP\"=\u003e5, \"IOT\"=\u003e6, \"ABRT\"=\u003e6, \"FPE\"=\u003e8, \"KILL\"=\u003e9, \"BUS\"=\u003e7, \"SEGV\"=\u003e11, \"SYS\"=\u003e31, \"PIPE\"=\u003e13, \"ALRM\"=\u003e14, \"TERM\"=\u003e15, \"URG\"=\u003e23, \"STOP\"=\u003e19, \"TSTP\"=\u003e20, \"CONT\"=\u003e18, \"CHLD\"=\u003e17, \"CLD\"=\u003e17, \"TTIN\"=\u003e21, \"TTOU\"=\u003e22, \"IO\"=\u003e29, \"XCPU\"=\u003e24, \"XFSZ\"=\u003e25, \"VTALRM\"=\u003e26, \"PROF\"=\u003e27, \"WINCH\"=\u003e28, \"USR1\"=\u003e10, \"USR2\"=\u003e12, \"PWR\"=\u003e30, \"POLL\"=\u003e29}","    # Press `Control + C` to quit means 'SIGINT'.","    def setup_signals","      begin","        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \"SIGTERM\"`.","        Signal.trap \"SIGTERM\" do","          graceful_stop # Let's step into this line.","","          raise SignalException, \"SIGTERM\"","        end","      rescue Exception","        log \"*** SIGTERM not implemented, signal based gracefully stopping unavailable!\"","      end","            ","      begin","        Signal.trap \"SIGUSR2\" do","          restart","        end","      rescue Exception","        log \"*** SIGUSR2 not implemented, signal based restart unavailable!\"","      end","","      begin","        Signal.trap \"SIGUSR1\" do","          phased_restart","        end","      rescue Exception","        log \"*** SIGUSR1 not implemented, signal based restart unavailable!\"","      end","","      begin","        Signal.trap \"SIGINT\" do","          if Puma.jruby?","            @status = :exit","            graceful_stop","            exit","          end","","          stop","        end","      rescue Exception","        log \"*** SIGINT not implemented, signal based gracefully stopping unavailable!\"","      end","","      begin","        Signal.trap \"SIGHUP\" do","          if @runner.redirected_io?","            @runner.redirect_io","          else","            stop","          end","        end","      rescue Exception","        log \"*** SIGHUP not implemented, signal based logs reopening unavailable!\"","      end","    end","    ","    def graceful_stop","      # @runner: instance of Puma::Single (for this example)","      @runner.stop_blocked # Let's step into this line.","      log \"=== puma shutdown: #{Time.now} ===\"","      log \"- Goodbye!\"","    end","  end","end","","# .gems/puma-3.12.0/lib/puma/launcher.rb","module Puma","  class Single \u003c Runner","    def run","      # ...","","      # @server: Puma::Server.new(app, @launcher.events, @options)","      @server = server = start_server # Let's step into this line.","","      # ...","      thread = server.run","      ","      # This line will suspend the main thread execution.","      # And the `thread`'s block (which is the method `handle_servers`) will be executed.  ","      thread.join","    end","      ","    def stop_blocked","      log \"- Gracefully stopping, waiting for requests to finish\"","      @control.stop(true) if @control","      # @server: instance of Puma::Server","      @server.stop(true) # Let's step into this line","    end","  end","end","","# .gems/puma-3.12.0/lib/puma/server.rb","module Puma","  class Server","    def initialize(app, events=Events.stdio, options={})","      # 'Puma::Util.pipe' returns `IO.pipe`.","      @check, @notify = Puma::Util.pipe # @check, @notify is a pair.","","      @status = :stop","    end","      ","    def run(background=true)","      # ...","      @thread_pool = ThreadPool.new(@min_threads,","                                    @max_threads,","                                    IOBuffer) do |client, buffer|","","        #...","        # Process the request.","        process_client(client, buffer)  ","        #...","      end","      ","      # 'Thread.current.object_id' returns '70144214949920', ","      # which is the same as the 'Thread.current.object_id' in Puma::Server#stop.","      # Current thread is the main thread here.","      puts \"#{Thread.current.object_id}\"","      ","      # The created @thread is the @thread in `stop` method below.","      @thread = Thread.new {","        # FYI, this is in the Puma starting process.      ","        # 'Thread.current.object_id' returns '70144220123860', ","        # which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run","        # def handle_servers","        #   begin","        #     # ...","        #   ensure","        #     # FYI, the 'ensure' part is in the Puma stopping process.","        #     puts \"#{Thread.current.object_id}\" # returns '70144220123860' too.","        #   end","        # end","        puts \"#{Thread.current.object_id}\" # returns '70144220123860'","        ","        handle_servers","      }","      return @thread","    end","      ","    # Stops the acceptor thread and then causes the worker threads to finish","    # off the request queue before finally exiting.","    def stop(sync=false)","      # This line will set '@status = :stop',","      # and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.","      # So that the code after `ios = IO.select sockets` will be executed.   ","      notify_safely(STOP_COMMAND) # Let's step into this line.","      ","      # 'Thread.current.object_id' returns '70144214949920', ","      # which is the same as the 'Thread.current.object_id' in Puma::Server#run.","      # Current thread is exactly the main thread here.","      puts \"#{Thread.current.object_id}\"","      ","      # The @thread is just the always running Thread created in `Puma::Server#run`.","      # Please look at method `Puma::Server#run`.","      # `@thread.join` will suspend the main thread execution.","      # And the code in @thread will continue be executed.","      @thread.join if @thread \u0026\u0026 sync","    end","    ","    def notify_safely(message)","      @notify \u003c\u003c message","    end","    ","    def handle_servers","      begin","        check = @check","        # sockets: [#\u003cIO:fd 23\u003e, #\u003cTCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u003e]","        sockets = [check] + @binder.ios","        pool = @thread_pool","        #..."," ","        while @status == :run","          # After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.","          # FYI, `@check, @notify = IO.pipe`.","          # def notify_safely(message)","          #   @notify \u003c\u003c message","          # end","          # sockets: [#\u003cIO:fd 23\u003e, #\u003cTCPServer:fd 22, AF_INET, 0.0.0.0, 3000\u003e]","          ios = IO.select sockets","            ","          ios.first.each do |sock|","            if sock == check","              # The @status is updated to :stop for this example in `handle_check`.","              break if handle_check # Let's step into this line.","            else","              if io = sock.accept_nonblock","                client = Client.new(io, @binder.env(sock))","                ","                # ...","                pool \u003c\u003c client","                pool.wait_until_not_full","              end","            end","          end","        end","        ","        # Let's step into `graceful_shutdown`.","        graceful_shutdown if @status == :stop || @status == :restart","        ","      # ...","      ensure","        # FYI, the 'ensure' part is in the Puma stopping process.","        # 'Thread.current.object_id' returns '70144220123860', ","        # which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run","        # @thread = Thread.new do","        #   # FYI, this is in the Puma starting process.","        #   puts \"#{Thread.current.object_id}\" # returns '70144220123860'","        #   handle_servers","        # end","        puts \"#{Thread.current.object_id}\"","          ","        @check.close","        @notify.close","","        # ...","      end","    end","    ","    def handle_check","      cmd = @check.read(1)","","      case cmd","      when STOP_COMMAND","        @status = :stop # The @status is updated to :stop for this example. ","        return true","      when HALT_COMMAND","        @status = :halt","        return true","      when RESTART_COMMAND","        @status = :restart","        return true","      end","","      return false","    end","    ","    def graceful_shutdown","      if @thread_pool","        @thread_pool.shutdown # Let's step into this line.","      end","    end    ","  end","end","```","","```ruby","module Puma","  class ThreadPool","    # Tell all threads in the pool to exit and wait for them to finish.","    def shutdown(timeout=-1)","      threads = @mutex.synchronize do","        @shutdown = true","        # `broadcast` will wakes up all threads waiting for this lock.","        @not_empty.broadcast","        @not_full.broadcast","","        # ...","        ","        # dup workers so that we join them all safely","        # @workers is an array.   ","        # @workers.dup will not create new thread.","        # @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). ","        # So ues @workers.dup here.","        @workers.dup","      end","","      # Wait for threads to finish without force shutdown.","      threads.each do |thread|","        thread.join","      end","","      @spawned = 0","      @workers = []","    end","","    def initialize(min, max, *extra, \u0026block)","      #..","      @mutex = Mutex.new","      @spawned = 0 # The count of @spawned threads.","      @todo = [] # @todo is requests (in Puma, it's Puma::Client instance) which need to be processed.  ","      @min = Integer(min) # @min threads count","      @block = block # block will be called in method `spawn_thread` to process a request.    ","      @workers = []","","      @mutex.synchronize do","        @min.times { spawn_thread } # Puma spawns @min count threads.","      end","    end","    ","    def spawn_thread","      @spawned += 1","","      # Run a new Thread now.","      # The block of the thread will be executed separately from the calling thread. ","      th = Thread.new(@spawned) do |spawned|","        block = @block","        mutex = @mutex","        #..."," ","        while true","          work = nil","","          continue = true","","          mutex.synchronize do","            while todo.empty?","              # ..."," ","              if @shutdown","                continue = false","                break","              end","","              # ...","              # After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.","              # Ruby will continue to execute the next line here.","              not_empty.wait mutex","              ","              @waiting -= 1","            end","","            # ...","          end","","          break unless continue","","          # ...","        end","","        mutex.synchronize do","          @spawned -= 1","          @workers.delete th","        end","      end # end of the Thread.new.","","      @workers \u003c\u003c th","","      th","    end","  end","end","```","","So all the threads in the ThreadPool joined and finished.","","Let's inspect the caller in block of `Signal.trap \"SIGTERM\"` below.","","```ruby","# .gems/puma-3.12.0/lib/puma/launcher.rb","module Puma","  # Puma::Launcher is the single entry point for starting a Puma server based on user","  # configuration.","  class Launcher","    def run","      #...","","      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. ","      setup_signals # Let's step into this line.","      ","      set_process_title","      ","      # Process.pid: 42264 ","      puts \"Process.pid: #{Process.pid}\"","      ","      @runner.run","","      # ...","    end","    ","    def setup_signals","      # ...","      begin","        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap \"SIGTERM\"`.","        Signal.trap \"SIGTERM\" do","          # I inspect `caller` to see the caller stack.","          # caller: [","          #   \"../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'\", ","          #   \"../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'\",","          #   \"../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'\",","          #   \"../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'\",","          #   \"../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'\",","          #   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\", ","          #   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'\", ","          #   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'\", ","          #   \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'\", ","          #   \"../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'\", ","          #   \"../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'\", ","          #   \"../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'\", ","          #   \"../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'\", ","          #   \"../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'\", ","          #   \"../gems/railties-5.2.2/lib/rails/commands.rb:18:in `\u003ctop (required)\u003e'\", ","          #   \"../path/to/your_project/bin/rails:5:in `require'\", ","          #   \"../path/to/your_project/bin/rails:5:in `\u003cmain\u003e'\"","          # ]","          puts \"caller: #{caller.inspect}\"","          ","          # Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.","          puts \"Process.pid: #{Process.pid}\"","          ","          graceful_stop","          ","          # This SignalException is not rescued in the caller stack.","          # So in the the caller stack, Ruby will goto the `ensure` part in","          # \"../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'\".","          # So the last code executed is `puts \"Exiting\" unless @options \u0026\u0026 options[:daemonize]`","          # when running `$ kill -s SIGTERM puma_process_id`.","          # You can search `puts \"Exiting\"` in this document to see it.","          raise SignalException, \"SIGTERM\"","        end","      rescue Exception","        # This `rescue` is only for `Signal.trap \"SIGTERM\"`, not for `raise SignalException, \"SIGTERM\"`.","        log \"*** SIGTERM not implemented, signal based gracefully stopping unavailable!\"","      end","    end","  end","end","```","","Welcome to point out the mistakes in this article :)"],"stylingDirectives":[[[0,36,"pl-mh"],[2,36,"pl-en"]],[[0,1,"pl-s"],[1,3,"pl-s"],[10,11,"pl-s"],[11,12,"pl-s"],[12,68,"pl-corl"],[68,70,"pl-s"],[70,71,"pl-s"],[71,124,"pl-corl"],[124,125,"pl-s"]],[[0,1,"pl-s"],[1,3,"pl-s"],[10,11,"pl-s"],[11,12,"pl-s"],[12,61,"pl-corl"],[61,63,"pl-s"],[63,64,"pl-s"],[64,79,"pl-corl"],[79,80,"pl-s"]],[[0,20,"pl-mh"],[3,20,"pl-en"]],[],[[2,3,"pl-v"],[4,5,"pl-s"],[47,48,"pl-s"],[48,49,"pl-s"],[49,91,"pl-corl"],[91,92,"pl-s"]],[[8,9,"pl-s"],[48,49,"pl-s"],[49,50,"pl-s"],[50,89,"pl-corl"],[89,90,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[62,63,"pl-s"],[63,64,"pl-s"],[64,118,"pl-corl"],[118,119,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,35,"pl-corl"],[35,36,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[39,40,"pl-s"],[40,41,"pl-s"],[41,75,"pl-corl"],[75,76,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[13,14,"pl-s"],[14,15,"pl-s"],[15,20,"pl-corl"],[20,21,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[18,19,"pl-s"],[19,20,"pl-s"],[20,30,"pl-corl"],[30,31,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[65,66,"pl-s"],[66,67,"pl-s"],[67,119,"pl-corl"],[119,120,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[20,21,"pl-s"],[21,22,"pl-s"],[22,34,"pl-corl"],[34,35,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[83,84,"pl-s"],[84,85,"pl-s"],[85,159,"pl-corl"],[159,160,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[23,24,"pl-s"],[24,38,"pl-c1"],[38,39,"pl-s"],[43,44,"pl-s"],[44,45,"pl-s"],[45,79,"pl-corl"],[79,80,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[13,14,"pl-s"],[14,15,"pl-s"],[15,20,"pl-corl"],[20,21,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[28,29,"pl-s"],[29,30,"pl-s"],[30,47,"pl-corl"],[47,48,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[22,23,"pl-s"],[23,24,"pl-s"],[24,38,"pl-corl"],[38,39,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,32,"pl-corl"],[32,33,"pl-s"]],[[6,7,"pl-v"],[8,9,"pl-s"],[21,22,"pl-s"],[22,23,"pl-s"],[23,36,"pl-corl"],[36,37,"pl-s"]],[[10,11,"pl-v"],[12,13,"pl-s"],[31,32,"pl-s"],[32,33,"pl-s"],[33,52,"pl-corl"],[52,53,"pl-s"]],[[10,11,"pl-v"],[12,13,"pl-s"],[18,19,"pl-s"],[19,26,"pl-c1"],[26,27,"pl-s"],[35,36,"pl-s"],[36,37,"pl-s"],[37,58,"pl-corl"],[58,59,"pl-s"]],[],[],[[0,45,"pl-mh"],[3,45,"pl-en"]],[[0,1,"pl-s"],[1,2,"pl-v"],[31,32,"pl-s"],[32,54,"pl-corl"],[54,55,"pl-s"],[55,56,"pl-s"],[56,78,"pl-corl"],[78,79,"pl-s"]],[],[[24,25,"pl-s"],[25,29,"pl-c1"],[29,30,"pl-s"]],[],[[27,28,"pl-s"],[28,32,"pl-c1"],[32,33,"pl-s"]],[],[[0,1,"pl-s"],[1,2,"pl-v"],[59,60,"pl-s"],[68,69,"pl-s"],[69,70,"pl-s"],[70,96,"pl-corl"],[96,97,"pl-s"]],[],[[0,43,"pl-mh"],[4,43,"pl-en"]],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[],[[0,1,"pl-v"]],[],[[32,33,"pl-s"],[33,47,"pl-c1"],[47,48,"pl-s"]],[],[[0,60,"pl-mh"],[3,60,"pl-en"]],[[38,39,"pl-s"],[39,63,"pl-c1"],[63,64,"pl-s"],[77,78,"pl-s"],[78,101,"pl-c1"],[101,102,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,67,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,23,"pl-en"],[26,30,"pl-e"],[26,30,"pl-en"]],[[6,9,"pl-k"],[10,17,"pl-en"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-c1"],[15,21,"pl-c1"],[22,25,"pl-k"],[46,48,"pl-k"],[50,56,"pl-smi"]],[[10,67,"pl-c"],[10,11,"pl-c"]],[[10,72,"pl-c"],[10,11,"pl-c"]],[[10,87,"pl-c"],[10,11,"pl-c"]],[[10,55,"pl-c"],[10,11,"pl-c"]],[[10,17,"pl-k"],[18,26,"pl-c1"]],[],[[10,13,"pl-c1"],[20,25,"pl-c1"]],[],[],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[],[[2,7,"pl-k"],[8,14,"pl-en"],[17,31,"pl-e"],[19,23,"pl-en"],[25,31,"pl-en"]],[[4,7,"pl-k"],[8,13,"pl-en"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[[6,76,"pl-c"],[6,7,"pl-c"]],[[6,76,"pl-c"],[6,7,"pl-c"]],[[6,96,"pl-c"],[6,7,"pl-c"]],[[6,70,"pl-c"],[6,7,"pl-c"]],[[6,48,"pl-c"],[6,7,"pl-c"]],[],[],[[6,11,"pl-k"],[12,48,"pl-c"],[12,13,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[36,37,"pl-s"],[37,40,"pl-c1"],[40,41,"pl-s"],[54,55,"pl-s"],[55,58,"pl-c1"],[58,59,"pl-s"],[81,82,"pl-s"],[82,86,"pl-c1"],[86,87,"pl-s"]],[],[[0,1,"pl-s"],[1,10,"pl-c1"],[10,11,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,13,"pl-c"],[0,1,"pl-c"]],[[0,16,"pl-k"],[17,37,"pl-s"],[17,18,"pl-pds"],[36,37,"pl-pds"]],[],[[4,9,"pl-c1"],[22,54,"pl-c"],[22,23,"pl-c"]],[[0,3,"pl-s"]],[],[[17,18,"pl-s"],[18,54,"pl-c1"],[54,55,"pl-s"],[68,69,"pl-s"],[69,73,"pl-c1"],[73,74,"pl-s"]],[],[[16,17,"pl-s"],[17,34,"pl-c1"],[34,35,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,36,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[11,15,"pl-smi"]],[[4,16,"pl-smi"],[17,18,"pl-k"],[19,29,"pl-smi"],[30,31,"pl-k"],[32,35,"pl-c1"]],[],[[4,17,"pl-k"],[18,28,"pl-c1"]],[],[[4,82,"pl-c"],[4,5,"pl-c"]],[[4,67,"pl-c"],[4,5,"pl-c"]],[[4,66,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,19,"pl-en"]],[[6,18,"pl-smi"],[19,22,"pl-k"],[43,45,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[8,9,"pl-s"],[9,45,"pl-c1"],[45,46,"pl-s"],[55,56,"pl-s"],[56,60,"pl-c1"],[60,61,"pl-s"],[63,64,"pl-s"],[64,82,"pl-c1"],[82,83,"pl-s"],[90,91,"pl-s"],[91,95,"pl-c1"],[95,96,"pl-s"]],[],[[9,10,"pl-s"],[10,19,"pl-c1"],[19,20,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,28,"pl-e"],[22,28,"pl-en"]],[[4,9,"pl-k"],[13,17,"pl-smi"]],[[6,9,"pl-k"],[10,19,"pl-en"],[20,24,"pl-smi"],[26,52,"pl-c"],[26,27,"pl-c"]],[[8,13,"pl-c1"],[24,25,"pl-k"],[31,63,"pl-c"],[31,32,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,1,"pl-s"],[0,1,"pl-pds"],[1,6,"pl-c1"],[8,19,"pl-c1"],[19,38,"pl-s"],[19,20,"pl-pds"],[37,38,"pl-pds"],[38,49,"pl-c1"],[49,51,"pl-s"],[49,50,"pl-pds"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,25,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,18,"pl-en"]],[[2,55,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,40,"pl-e"],[22,27,"pl-en"],[29,40,"pl-en"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,4,"pl-s"],[3,4,"pl-pds"],[4,15,"pl-c1"],[17,28,"pl-c1"],[28,38,"pl-s"],[28,29,"pl-pds"],[37,38,"pl-pds"],[38,43,"pl-c1"],[53,60,"pl-s"],[53,54,"pl-pds"]],[[0,0,"pl-s"]],[[0,62,"pl-s"],[61,62,"pl-pds"],[63,64,"pl-k"],[70,71,"pl-k"],[85,87,"pl-s"],[85,86,"pl-pds"]],[[0,0,"pl-s"]],[[0,50,"pl-s"],[49,50,"pl-pds"],[59,61,"pl-s"],[59,60,"pl-pds"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,13,"pl-c"],[0,1,"pl-c"]],[[0,16,"pl-k"],[17,37,"pl-s"],[17,18,"pl-pds"],[36,37,"pl-pds"],[38,66,"pl-c"],[38,39,"pl-c"]],[],[[4,9,"pl-c1"],[22,54,"pl-c"],[22,23,"pl-c"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,25,"pl-c"],[0,1,"pl-c"]],[[0,29,"pl-c"],[0,1,"pl-c"]],[[0,16,"pl-k"],[17,30,"pl-s"],[17,18,"pl-pds"],[29,30,"pl-pds"],[31,59,"pl-c"],[31,32,"pl-c"]],[],[[0,35,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-c1"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,25,"pl-c"],[0,1,"pl-c"]],[[0,16,"pl-k"],[17,23,"pl-s"],[17,18,"pl-pds"],[22,23,"pl-pds"]],[],[[0,7,"pl-k"],[8,19,"pl-s"],[8,9,"pl-pds"],[18,19,"pl-pds"]],[],[[0,56,"pl-c"],[0,1,"pl-c"]],[[0,56,"pl-c"],[0,1,"pl-c"]],[[0,7,"pl-c1"],[16,17,"pl-k"],[17,22,"pl-c1"]],[],[[0,6,"pl-k"],[7,18,"pl-en"]],[[2,55,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,40,"pl-e"],[22,27,"pl-en"],[29,40,"pl-en"]],[[25,28,"pl-c1"]],[[31,32,"pl-k"],[33,36,"pl-c1"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[8,9,"pl-s"],[9,33,"pl-c1"],[33,34,"pl-s"],[38,39,"pl-s"],[39,54,"pl-c1"],[54,55,"pl-s"],[57,58,"pl-s"],[58,76,"pl-c1"],[76,77,"pl-s"],[81,82,"pl-s"],[82,115,"pl-c1"],[115,116,"pl-s"]],[],[[17,18,"pl-s"],[18,22,"pl-c1"],[22,23,"pl-s"]],[],[[0,1,"pl-s"],[1,5,"pl-c1"],[5,6,"pl-s"],[36,37,"pl-s"],[37,70,"pl-c1"],[70,71,"pl-s"]],[],[[4,5,"pl-s"],[5,9,"pl-c1"],[9,10,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,37,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"],[17,24,"pl-e"],[17,24,"pl-en"]],[[4,7,"pl-k"],[8,12,"pl-en"],[13,16,"pl-smi"],[18,108,"pl-c"],[18,19,"pl-c"]],[[10,11,"pl-k"]],[[23,64,"pl-c"],[23,24,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,42,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,28,"pl-e"],[22,28,"pl-en"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,25,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,18,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,40,"pl-e"],[22,27,"pl-en"],[29,40,"pl-en"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,21,"pl-s"],[20,21,"pl-pds"],[21,32,"pl-c1"],[34,45,"pl-c1"],[46,47,"pl-k"],[48,53,"pl-c1"],[55,66,"pl-c1"],[67,68,"pl-k"],[69,74,"pl-c1"],[76,82,"pl-c1"],[83,84,"pl-k"],[85,90,"pl-c1"],[92,99,"pl-c1"],[99,101,"pl-s"],[99,100,"pl-pds"]],[[0,0,"pl-s"]],[[0,4,"pl-s"],[3,4,"pl-pds"],[4,15,"pl-c1"],[17,28,"pl-c1"],[29,32,"pl-k"],[45,50,"pl-c1"],[51,62,"pl-s"],[51,52,"pl-pds"],[61,62,"pl-pds"],[62,66,"pl-c1"],[66,68,"pl-s"],[66,67,"pl-pds"]],[[0,0,"pl-s"]],[[0,15,"pl-s"],[14,15,"pl-pds"],[33,45,"pl-s"],[33,34,"pl-pds"]],[[0,0,"pl-s"]],[[0,1,"pl-s"],[0,1,"pl-pds"],[9,76,"pl-s"],[9,10,"pl-pds"],[75,76,"pl-pds"],[86,89,"pl-k"],[89,91,"pl-s"],[89,90,"pl-pds"]],[[0,0,"pl-s"]],[[0,33,"pl-s"],[32,33,"pl-pds"],[41,43,"pl-s"],[41,42,"pl-pds"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,42,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,28,"pl-e"],[22,28,"pl-en"]],[[4,7,"pl-k"],[8,16,"pl-en"]],[[6,11,"pl-k"],[28,70,"pl-c"],[28,29,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,61,"pl-s"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,3,"pl-k"],[4,12,"pl-en"]],[[15,16,"pl-k"],[17,22,"pl-k"],[23,96,"pl-c"],[23,24,"pl-c"]],[],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,15,"pl-en"]],[[4,7,"pl-k"],[8,16,"pl-en"]],[[6,51,"pl-c"],[6,7,"pl-c"]],[[6,67,"pl-c"],[6,7,"pl-c"]],[[6,15,"pl-smi"],[16,19,"pl-k"],[20,23,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,0,"pl-s"]],[[0,3,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[2,3,"pl-pds"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,5,"pl-k"],[6,17,"pl-en"]],[[4,16,"pl-smi"],[17,20,"pl-k"],[41,43,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[3,4,"pl-s"],[4,32,"pl-c1"],[32,33,"pl-s"],[37,38,"pl-s"],[38,55,"pl-c1"],[55,56,"pl-s"]],[],[[23,24,"pl-s"],[24,41,"pl-c1"],[41,42,"pl-s"]],[],[[0,1,"pl-s"],[1,18,"pl-c1"],[18,19,"pl-s"]],[],[[25,26,"pl-s"],[26,43,"pl-c1"],[43,44,"pl-s"]],[],[[46,47,"pl-s"],[47,64,"pl-c1"],[64,65,"pl-s"]],[],[[0,17,"pl-mh"],[3,17,"pl-en"]],[[26,27,"pl-s"],[27,33,"pl-c1"],[33,34,"pl-s"],[41,42,"pl-s"],[42,65,"pl-c1"],[65,66,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,25,"pl-c"],[0,1,"pl-c"]],[[0,4,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,18,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,40,"pl-e"],[22,27,"pl-en"],[29,40,"pl-en"]],[[4,67,"pl-c"],[4,5,"pl-c"]],[[4,66,"pl-c"],[4,5,"pl-c"]],[[25,28,"pl-c1"],[30,80,"pl-c"],[30,31,"pl-c"]],[[31,32,"pl-k"],[33,36,"pl-c1"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,15,"pl-en"]],[[4,9,"pl-k"],[13,17,"pl-smi"]],[[6,41,"pl-c"],[6,7,"pl-c"]],[[6,78,"pl-c"],[6,7,"pl-c"]],[[15,22,"pl-c1"],[24,27,"pl-c1"],[28,37,"pl-c1"]],[],[[6,108,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,18,"pl-en"]],[[8,59,"pl-c"],[8,9,"pl-c"]],[[8,105,"pl-c"],[8,9,"pl-c"]],[[8,17,"pl-smi"],[18,21,"pl-k"],[22,25,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[],[[2,7,"pl-k"],[8,14,"pl-en"],[17,24,"pl-e"],[17,24,"pl-en"]],[[2,5,"pl-k"]],[],[[2,7,"pl-k"],[8,19,"pl-en"],[22,28,"pl-e"],[22,28,"pl-en"]],[[4,9,"pl-k"],[13,17,"pl-smi"]],[[6,9,"pl-k"],[10,18,"pl-en"]],[[8,61,"pl-c"],[8,9,"pl-c"]],[[8,70,"pl-c"],[8,9,"pl-c"]],[[21,22,"pl-k"],[23,28,"pl-k"]],[],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,23,"pl-en"]],[[6,12,"pl-k"],[13,17,"pl-c1"],[18,20,"pl-k"],[21,36,"pl-smi"]],[[6,21,"pl-smi"],[22,23,"pl-k"],[24,28,"pl-c1"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,100,"pl-c"],[11,12,"pl-c"]],[[4,7,"pl-k"]],[],[[4,34,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,14,"pl-en"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,110,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[14,17,"pl-k"],[18,29,"pl-c1"],[31,44,"pl-c1"],[45,48,"pl-k"],[49,53,"pl-c1"],[54,59,"pl-k"],[70,74,"pl-c1"],[75,80,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[12,13,"pl-s"],[13,73,"pl-c1"],[73,74,"pl-s"],[83,84,"pl-s"],[84,88,"pl-c1"],[88,89,"pl-s"]],[],[[15,16,"pl-s"],[16,22,"pl-c1"],[22,23,"pl-s"],[68,69,"pl-s"],[69,75,"pl-c1"],[75,76,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[11,15,"pl-smi"]],[[4,7,"pl-k"],[8,21,"pl-en"]],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[3,4,"pl-s"],[4,52,"pl-c1"],[52,53,"pl-s"],[62,63,"pl-s"],[63,67,"pl-c1"],[67,68,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"]],[[4,9,"pl-k"],[10,23,"pl-en"],[26,56,"pl-e"],[28,33,"pl-en"],[35,41,"pl-en"],[43,56,"pl-en"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,9,"pl-k"],[10,23,"pl-en"],[26,57,"pl-e"],[28,33,"pl-en"],[35,42,"pl-en"],[44,57,"pl-en"]],[[6,19,"pl-k"],[20,31,"pl-c1"]],[],[[6,9,"pl-k"],[10,20,"pl-en"],[21,25,"pl-smi"],[26,27,"pl-k"],[28,31,"pl-c1"]],[[8,13,"pl-k"]],[[8,12,"pl-c"],[8,9,"pl-c"]],[[8,19,"pl-smi"],[20,21,"pl-k"],[22,27,"pl-c1"],[29,42,"pl-c1"],[44,64,"pl-c1"],[65,68,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[],[[2,7,"pl-k"],[8,15,"pl-en"]],[[4,9,"pl-k"],[10,23,"pl-en"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,37,"pl-mh"],[3,37,"pl-en"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,20,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-c1"],[30,32,"pl-k"]],[[7,19,"pl-s"],[7,8,"pl-pds"],[18,19,"pl-pds"],[20,42,"pl-c"],[20,21,"pl-c"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,8,"pl-mh"],[4,8,"pl-en"]],[[69,70,"pl-s"],[70,97,"pl-c1"],[97,98,"pl-s"]],[],[[46,47,"pl-s"],[47,74,"pl-c1"],[74,75,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,39,"pl-c"],[0,1,"pl-c"]],[[0,7,"pl-k"],[8,16,"pl-s"],[8,9,"pl-pds"],[15,16,"pl-pds"]],[],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,57,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,72,"pl-c"],[2,3,"pl-c"]],[[2,82,"pl-c"],[2,3,"pl-c"]],[[2,63,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,78,"pl-c"],[2,3,"pl-c"]],[[2,77,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,66,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,7,"pl-k"],[8,18,"pl-en"],[19,22,"pl-smi"],[24,30,"pl-smi"],[30,31,"pl-k"],[31,37,"pl-c1"],[45,52,"pl-smi"],[52,53,"pl-k"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,68,"pl-c"],[6,7,"pl-c"]],[[6,75,"pl-c"],[6,7,"pl-c"]],[[6,15,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-smi"],[11,12,"pl-k"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[[4,7,"pl-k"]],[],[[4,67,"pl-c"],[4,5,"pl-c"]],[[4,5,"pl-c"],[4,5,"pl-c"]],[[4,79,"pl-c"],[4,5,"pl-c"]],[[4,76,"pl-c"],[4,5,"pl-c"]],[[4,16,"pl-c"],[4,5,"pl-c"]],[[4,5,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,29,"pl-smi"],[31,37,"pl-smi"]],[[6,11,"pl-k"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-k"],[14,18,"pl-c1"]],[[10,38,"pl-c"],[10,11,"pl-c"]],[[10,14,"pl-k"],[46,81,"pl-c"],[46,47,"pl-c"]],[[10,14,"pl-k"],[15,19,"pl-c1"]],[[12,18,"pl-k"],[19,25,"pl-k"],[26,41,"pl-smi"]],[],[],[[12,22,"pl-c1"],[43,45,"pl-k"]],[],[[12,18,"pl-k"],[32,39,"pl-smi"],[40,42,"pl-k"],[43,47,"pl-c1"]],[[27,28,"pl-k"],[29,34,"pl-c1"]],[[33,52,"pl-smi"]],[[14,22,"pl-smi"]],[[14,20,"pl-k"]],[[12,15,"pl-k"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[6,12,"pl-k"]],[],[[21,23,"pl-k"]],[[8,12,"pl-c"],[8,9,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,70,"pl-c"],[4,5,"pl-c"]],[[4,67,"pl-c"],[4,5,"pl-c"]],[[4,68,"pl-c"],[4,5,"pl-c"]],[[4,14,"pl-c"],[4,5,"pl-c"]],[[4,5,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,26,"pl-smi"],[28,33,"pl-smi"]],[[10,11,"pl-k"]],[[6,12,"pl-c"],[6,7,"pl-c"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,68,"pl-c"],[6,7,"pl-c"]],[[6,75,"pl-c"],[6,7,"pl-c"]],[[6,15,"pl-c"],[6,7,"pl-c"]],[[32,33,"pl-k"],[34,38,"pl-smi"],[49,77,"pl-c"],[49,50,"pl-c"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,12,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,46,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,21,"pl-en"]],[[4,9,"pl-k"],[10,26,"pl-en"]],[[6,9,"pl-k"],[10,20,"pl-en"],[21,27,"pl-smi"],[29,32,"pl-smi"]],[[8,15,"pl-smi"],[16,17,"pl-k"]],[[8,12,"pl-smi"],[13,14,"pl-k"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,14,"pl-en"],[15,18,"pl-smi"]],[[12,17,"pl-c1"],[19,30,"pl-c1"],[32,33,"pl-k"],[34,41,"pl-smi"]],[[8,62,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-smi"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,13,"pl-mh"],[4,13,"pl-en"]],[[26,27,"pl-s"],[27,69,"pl-c1"],[69,70,"pl-s"],[76,77,"pl-s"],[77,81,"pl-c1"],[81,82,"pl-s"],[86,87,"pl-s"],[87,111,"pl-c1"],[111,112,"pl-s"]],[],[[15,16,"pl-s"],[16,33,"pl-c1"],[33,34,"pl-s"]],[],[[12,13,"pl-s"],[13,17,"pl-c1"],[17,18,"pl-s"]],[],[[19,20,"pl-s"],[20,24,"pl-c1"],[24,25,"pl-s"],[36,37,"pl-s"],[37,55,"pl-c1"],[55,56,"pl-s"],[66,67,"pl-s"],[67,91,"pl-c1"],[91,92,"pl-s"],[114,115,"pl-s"],[115,119,"pl-c1"],[119,120,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,37,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"],[17,24,"pl-e"],[17,24,"pl-en"]],[[4,7,"pl-k"],[8,12,"pl-en"],[13,16,"pl-smi"],[18,83,"pl-c"],[18,19,"pl-c"]],[[10,11,"pl-k"]],[[23,50,"pl-c"],[23,24,"pl-c"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,12,"pl-c"],[6,7,"pl-c"]],[[6,17,"pl-c"],[6,7,"pl-c"]],[[6,103,"pl-c"],[6,7,"pl-c"]],[[6,83,"pl-c"],[6,7,"pl-c"]],[[6,73,"pl-c"],[6,7,"pl-c"]],[[6,95,"pl-c"],[6,7,"pl-c"]],[[6,78,"pl-c"],[6,7,"pl-c"]],[[6,111,"pl-c"],[6,7,"pl-c"]],[[6,97,"pl-c"],[6,7,"pl-c"]],[[6,101,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[6,92,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,86,"pl-c"],[6,7,"pl-c"]],[[6,80,"pl-c"],[6,7,"pl-c"]],[[6,97,"pl-c"],[6,7,"pl-c"]],[[6,81,"pl-c"],[6,7,"pl-c"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,55,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[6,74,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,92,"pl-c"],[6,7,"pl-c"]],[[6,62,"pl-c"],[6,7,"pl-c"]],[[6,90,"pl-c"],[6,7,"pl-c"]],[[6,70,"pl-c"],[6,7,"pl-c"]],[[6,100,"pl-c"],[6,7,"pl-c"]],[[6,92,"pl-c"],[6,7,"pl-c"]],[[6,103,"pl-c"],[6,7,"pl-c"]],[[6,91,"pl-c"],[6,7,"pl-c"]],[[6,94,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[6,77,"pl-c"],[6,7,"pl-c"]],[[6,61,"pl-c"],[6,7,"pl-c"]],[[6,75,"pl-c"],[6,7,"pl-c"]],[[6,70,"pl-c"],[6,7,"pl-c"]],[[6,81,"pl-c"],[6,7,"pl-c"]],[[6,59,"pl-c"],[6,7,"pl-c"]],[[6,57,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,38,"pl-s"],[11,12,"pl-pds"],[20,22,"pl-pse"],[22,36,"pl-s1"],[22,28,"pl-c1"],[36,37,"pl-pse"],[37,38,"pl-pds"]],[],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,109,"pl-c"],[6,7,"pl-c"]],[[6,105,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-smi"],[11,13,"pl-k"],[14,29,"pl-smi"],[44,114,"pl-c"],[44,45,"pl-c"]],[[8,12,"pl-smi"],[13,16,"pl-k"],[17,22,"pl-k"]],[[10,161,"pl-c"],[10,11,"pl-c"]],[[16,17,"pl-k"],[43,70,"pl-c"],[43,44,"pl-c"]],[[10,49,"pl-c"],[10,11,"pl-c"]],[[28,29,"pl-k"]],[[10,101,"pl-c"],[10,11,"pl-c"]],[[44,110,"pl-c"],[44,45,"pl-c"]],[[8,11,"pl-k"]],[],[],[[0,45,"pl-c"],[0,1,"pl-c"]],[[0,60,"pl-c"],[0,1,"pl-c"]],[[0,69,"pl-c"],[0,1,"pl-c"]],[[0,28,"pl-c"],[0,1,"pl-c"]],[[0,66,"pl-c"],[0,1,"pl-c"]],[[0,82,"pl-c"],[0,1,"pl-c"]],[[0,102,"pl-c"],[0,1,"pl-c"]],[[0,35,"pl-c"],[0,1,"pl-c"]],[[0,33,"pl-c"],[0,1,"pl-c"]],[[0,26,"pl-c"],[0,1,"pl-c"]],[[0,30,"pl-c"],[0,1,"pl-c"]],[[0,19,"pl-c"],[0,1,"pl-c"]],[[0,11,"pl-c"],[0,1,"pl-c"]],[[6,10,"pl-smi"]],[[4,7,"pl-k"]],[],[[4,64,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,16,"pl-en"]],[[6,20,"pl-c1"],[22,29,"pl-c1"],[31,39,"pl-c1"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,42,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,19,"pl-en"],[22,28,"pl-e"],[22,28,"pl-en"]],[[4,7,"pl-k"],[8,32,"pl-en"]],[[20,21,"pl-k"],[22,44,"pl-c1"],[45,48,"pl-k"],[49,53,"pl-c1"]],[[32,60,"pl-c"],[32,33,"pl-c"]],[[4,7,"pl-k"]],[],[[4,9,"pl-k"],[10,32,"pl-en"]],[[6,17,"pl-k"],[18,25,"pl-c1"],[27,33,"pl-c1"],[35,39,"pl-c1"]],[],[[6,9,"pl-k"],[10,20,"pl-en"],[21,24,"pl-smi"],[26,32,"pl-smi"],[34,39,"pl-smi"]],[[8,12,"pl-smi"],[13,14,"pl-k"]],[[8,15,"pl-smi"],[16,17,"pl-k"]],[[8,14,"pl-smi"],[15,16,"pl-k"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,21,"pl-en"]],[[8,22,"pl-c1"],[24,39,"pl-c1"],[40,43,"pl-k"],[44,46,"pl-k"],[48,58,"pl-smi"]],[[10,12,"pl-k"]],[[29,43,"pl-c1"],[45,48,"pl-c1"]],[[10,13,"pl-k"]],[],[[27,31,"pl-c1"],[33,41,"pl-c1"]],[],[[10,12,"pl-k"]],[[20,21,"pl-k"],[56,58,"pl-k"]],[],[[29,43,"pl-c1"],[45,51,"pl-c1"],[59,67,"pl-s"],[59,60,"pl-pds"],[66,67,"pl-pds"],[76,82,"pl-c1"],[121,129,"pl-c1"]],[[10,13,"pl-k"]],[],[[10,12,"pl-k"],[24,25,"pl-k"]],[[12,19,"pl-k"],[20,53,"pl-s"],[20,21,"pl-pds"],[52,53,"pl-pds"]],[[29,33,"pl-c1"],[35,40,"pl-c1"]],[[10,13,"pl-k"]],[],[[10,12,"pl-k"],[38,40,"pl-k"],[41,46,"pl-c1"]],[[12,65,"pl-c"],[12,13,"pl-c"]],[[12,63,"pl-c"],[12,13,"pl-c"]],[],[[29,33,"pl-c1"],[35,39,"pl-c1"]],[[10,13,"pl-k"]],[],[[27,41,"pl-c1"],[43,51,"pl-c1"]],[],[[27,31,"pl-c1"],[33,40,"pl-c1"]],[[27,31,"pl-c1"],[33,47,"pl-c1"],[48,54,"pl-k"]],[[27,41,"pl-c1"],[43,52,"pl-c1"]],[[27,41,"pl-c1"],[43,51,"pl-c1"]],[],[[27,32,"pl-c1"],[34,38,"pl-c1"],[40,46,"pl-c1"]],[[27,41,"pl-c1"],[43,57,"pl-c1"]],[[27,41,"pl-c1"],[43,58,"pl-c1"]],[],[[10,16,"pl-k"]],[[29,43,"pl-c1"],[45,53,"pl-c1"]],[[10,13,"pl-k"]],[],[[27,41,"pl-c1"],[43,52,"pl-c1"]],[[27,41,"pl-c1"],[43,50,"pl-c1"],[51,57,"pl-k"]],[],[[10,12,"pl-k"],[13,14,"pl-k"],[30,32,"pl-k"]],[[12,14,"pl-k"],[32,34,"pl-k"],[60,75,"pl-c1"],[77,81,"pl-c1"],[83,85,"pl-k"],[86,87,"pl-k"],[115,122,"pl-c1"]],[[37,44,"pl-c1"],[46,47,"pl-k"],[48,52,"pl-c1"]],[[12,15,"pl-k"]],[],[[29,43,"pl-c1"],[45,50,"pl-c1"]],[[10,13,"pl-k"]],[],[[10,16,"pl-k"]],[[29,43,"pl-c1"],[45,66,"pl-c1"],[68,78,"pl-c1"]],[[10,13,"pl-k"]],[],[[27,31,"pl-c1"],[33,37,"pl-c1"]],[[27,31,"pl-c1"],[33,47,"pl-c1"]],[[27,31,"pl-c1"],[33,37,"pl-c1"],[39,49,"pl-s"],[39,40,"pl-pds"],[48,49,"pl-pds"]],[],[[27,31,"pl-c1"],[33,47,"pl-c1"],[48,54,"pl-k"]],[[8,11,"pl-k"]],[[7,10,"pl-k"]],[[5,8,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,65,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,21,"pl-en"]],[[2,7,"pl-k"],[8,23,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"],[12,17,"pl-smi"],[19,20,"pl-k"],[20,24,"pl-smi"],[26,27,"pl-k"],[27,32,"pl-smi"]],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,24,"pl-en"],[25,30,"pl-smi"],[32,36,"pl-smi"],[38,43,"pl-smi"]],[[6,16,"pl-c1"],[17,20,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,13,"pl-en"],[14,17,"pl-smi"],[18,19,"pl-k"],[20,24,"pl-c1"],[25,28,"pl-k"]],[[6,51,"pl-c"],[6,7,"pl-c"]],[[17,18,"pl-k"],[58,60,"pl-k"],[62,63,"pl-smi"],[65,75,"pl-smi"]],[[8,52,"pl-c"],[8,9,"pl-c"]],[[8,200,"pl-c"],[8,9,"pl-c"]],[[28,56,"pl-c"],[28,29,"pl-c"]],[[6,9,"pl-k"]],[],[],[[4,7,"pl-k"]],[],[[4,9,"pl-k"],[10,20,"pl-en"]],[[6,9,"pl-k"],[10,20,"pl-en"],[21,26,"pl-smi"],[28,32,"pl-smi"],[34,39,"pl-smi"]],[[8,14,"pl-smi"],[15,16,"pl-k"]],[[8,13,"pl-smi"],[15,16,"pl-k"]],[[8,14,"pl-smi"],[15,16,"pl-k"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,15,"pl-en"],[16,19,"pl-smi"]],[[8,116,"pl-c"],[8,9,"pl-c"]],[[8,57,"pl-c"],[8,9,"pl-c"]],[[8,102,"pl-c"],[8,9,"pl-c"]],[[14,17,"pl-k"],[23,24,"pl-k"],[30,31,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[0,60,"pl-mh"],[4,60,"pl-en"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,19,"pl-c"],[0,1,"pl-c"]],[[0,45,"pl-c"],[0,1,"pl-c"]],[[0,60,"pl-c"],[0,1,"pl-c"]],[[0,69,"pl-c"],[0,1,"pl-c"]],[[0,28,"pl-c"],[0,1,"pl-c"]],[[0,66,"pl-c"],[0,1,"pl-c"]],[[0,82,"pl-c"],[0,1,"pl-c"]],[[0,102,"pl-c"],[0,1,"pl-c"]],[[0,35,"pl-c"],[0,1,"pl-c"]],[[0,33,"pl-c"],[0,1,"pl-c"]],[[0,26,"pl-c"],[0,1,"pl-c"]],[[0,30,"pl-c"],[0,1,"pl-c"]],[[0,19,"pl-c"],[0,1,"pl-c"]],[[0,11,"pl-c"],[0,1,"pl-c"]],[[0,3,"pl-s"]],[[49,53,"pl-s"],[50,53,"pl-corl"]],[],[[0,1,"pl-s"],[1,61,"pl-c1"],[61,62,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,66,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,21,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,18,"pl-en"]],[[6,9,"pl-k"],[10,20,"pl-en"],[21,27,"pl-smi"],[28,29,"pl-k"],[30,44,"pl-c1"]],[[8,12,"pl-smi"],[16,17,"pl-k"],[18,25,"pl-c1"],[27,33,"pl-c1"],[34,37,"pl-k"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,25,"pl-c1"],[27,33,"pl-c1"],[34,37,"pl-k"],[38,42,"pl-smi"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,14,"pl-en"],[15,18,"pl-smi"]],[[12,13,"pl-k"],[32,73,"pl-c"],[32,33,"pl-c"]],[[22,23,"pl-k"],[24,31,"pl-c1"],[33,39,"pl-c1"],[41,46,"pl-c1"]],[[8,15,"pl-smi"],[27,55,"pl-c"],[27,28,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[],[[0,64,"pl-c"],[0,1,"pl-c"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,16,"pl-en"]],[[6,11,"pl-k"],[12,24,"pl-en"],[27,42,"pl-e"],[29,42,"pl-en"]],[[6,9,"pl-k"]],[],[[6,19,"pl-k"],[20,27,"pl-c1"]],[],[[6,9,"pl-k"],[10,20,"pl-en"],[21,27,"pl-smi"]],[[8,15,"pl-smi"],[16,17,"pl-k"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,15,"pl-en"],[16,19,"pl-smi"]],[[30,32,"pl-k"],[34,39,"pl-smi"],[41,51,"pl-smi"],[53,58,"pl-smi"],[60,91,"pl-c"],[60,61,"pl-c"]],[[22,23,"pl-k"]],[[22,23,"pl-k"]],[[22,23,"pl-k"]],[],[[10,16,"pl-k"]],[[28,29,"pl-k"],[48,49,"pl-k"],[62,67,"pl-c1"],[68,71,"pl-s"],[68,69,"pl-pds"],[70,71,"pl-pds"]],[[26,27,"pl-k"]],[[26,27,"pl-k"],[28,31,"pl-s"],[28,29,"pl-pds"],[30,31,"pl-pds"],[32,33,"pl-k"],[48,54,"pl-k"],[81,84,"pl-s"],[81,82,"pl-pds"],[83,84,"pl-pds"]],[[10,13,"pl-k"]],[],[[21,22,"pl-k"],[75,78,"pl-smi"]],[[37,45,"pl-c1"],[47,52,"pl-c1"]],[],[],[[30,31,"pl-k"]],[],[[10,70,"pl-c"],[10,11,"pl-c"]],[[10,88,"pl-c"],[10,11,"pl-c"]],[[32,33,"pl-k"],[55,87,"pl-c"],[55,56,"pl-c"]],[],[[10,12,"pl-k"],[13,19,"pl-s"],[13,14,"pl-pds"],[18,19,"pl-pds"],[20,22,"pl-k"],[31,42,"pl-s"],[31,32,"pl-pds"],[41,42,"pl-pds"]],[[32,33,"pl-k"]],[[32,33,"pl-k"]],[[32,33,"pl-k"]],[[12,16,"pl-k"]],[[10,13,"pl-k"]],[],[[10,16,"pl-k"]],[[8,11,"pl-k"]],[],[[9,12,"pl-c1"],[16,27,"pl-s"],[16,17,"pl-pds"],[26,27,"pl-pds"],[31,37,"pl-s"],[31,32,"pl-pds"],[36,37,"pl-pds"],[42,53,"pl-s"],[42,43,"pl-pds"],[52,53,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,9,"pl-k"],[10,21,"pl-en"],[22,25,"pl-smi"]],[[15,16,"pl-k"],[79,80,"pl-smi"]],[],[],[],[[15,16,"pl-k"]],[[10,12,"pl-k"]],[],[[10,14,"pl-k"]],[],[[10,13,"pl-k"]],[],[[24,25,"pl-k"],[25,36,"pl-c1"]],[],[[23,24,"pl-smi"]],[[21,22,"pl-k"]],[[26,27,"pl-k"]],[[55,59,"pl-smi"],[61,64,"pl-smi"]],[[41,42,"pl-k"],[43,48,"pl-c1"],[67,69,"pl-k"]],[],[],[],[[6,9,"pl-k"]],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,66,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,21,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,18,"pl-en"]],[[6,11,"pl-k"],[12,22,"pl-en"],[25,42,"pl-e"],[25,32,"pl-en"],[34,42,"pl-en"]],[[8,11,"pl-k"],[12,17,"pl-en"],[18,21,"pl-smi"]],[[21,22,"pl-k"],[43,92,"pl-c"],[43,44,"pl-c"]],[[21,22,"pl-k"],[39,67,"pl-c"],[39,40,"pl-c"]],[[10,50,"pl-c"],[10,11,"pl-c"]],[[10,80,"pl-c"],[10,11,"pl-c"]],[[21,22,"pl-k"]],[[38,45,"pl-c1"],[58,86,"pl-c"],[58,59,"pl-c"]],[[8,14,"pl-k"],[15,31,"pl-c1"],[33,45,"pl-c1"]],[[10,12,"pl-k"],[13,33,"pl-smi"]],[[12,17,"pl-k"]],[[10,14,"pl-k"]],[[12,18,"pl-k"],[20,23,"pl-c1"],[27,38,"pl-s"],[27,28,"pl-pds"],[37,38,"pl-pds"],[42,48,"pl-s"],[42,43,"pl-pds"],[47,48,"pl-pds"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[],[[8,15,"pl-k"]],[],[[8,11,"pl-k"],[12,22,"pl-en"],[23,26,"pl-smi"]],[],[[8,14,"pl-k"],[15,24,"pl-c1"]],[[10,15,"pl-k"],[16,32,"pl-c1"],[34,46,"pl-c1"]],[[8,11,"pl-k"]],[],[[8,11,"pl-k"],[12,20,"pl-en"],[21,31,"pl-smi"],[33,39,"pl-smi"],[41,44,"pl-smi"],[46,49,"pl-smi"]],[[48,76,"pl-c"],[48,49,"pl-c"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,56,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,7,"pl-k"],[8,13,"pl-en"],[16,40,"pl-e"],[16,34,"pl-en"],[36,40,"pl-en"]],[],[],[[4,7,"pl-k"],[8,28,"pl-en"],[8,12,"pl-c1"]],[[6,22,"pl-smi"],[23,26,"pl-k"],[43,46,"pl-c1"],[47,60,"pl-sr"],[62,64,"pl-s"],[62,63,"pl-pds"],[63,64,"pl-pds"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,27,"pl-en"],[8,12,"pl-c1"],[28,35,"pl-smi"]],[[6,20,"pl-c1"],[22,30,"pl-c1"],[31,34,"pl-k"],[39,41,"pl-k"],[43,46,"pl-smi"]],[[20,21,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[20,37,"pl-c1"],[39,47,"pl-c1"],[48,64,"pl-c1"],[66,81,"pl-c1"],[82,85,"pl-k"]],[],[[4,7,"pl-k"],[8,22,"pl-en"],[8,12,"pl-c1"],[23,27,"pl-smi"]],[[28,29,"pl-k"]],[[6,11,"pl-k"]],[[4,7,"pl-k"]],[],[[4,74,"pl-c"],[4,5,"pl-c"]],[[4,39,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,21,"pl-en"],[8,12,"pl-c1"],[22,26,"pl-smi"],[28,31,"pl-smi"],[33,36,"pl-smi"]],[[6,8,"pl-k"]],[[40,43,"pl-smi"],[45,48,"pl-k"]],[[6,10,"pl-k"]],[[8,96,"pl-c"],[8,9,"pl-c"]],[[8,94,"pl-c"],[8,9,"pl-c"]],[[8,65,"pl-c"],[8,9,"pl-c"]],[[8,24,"pl-c"],[8,9,"pl-c"]],[[8,33,"pl-c"],[8,9,"pl-c"]],[[8,34,"pl-c"],[8,9,"pl-c"]],[[8,71,"pl-c"],[8,9,"pl-c"]],[[8,63,"pl-c"],[8,9,"pl-c"]],[[8,54,"pl-c"],[8,9,"pl-c"]],[[8,59,"pl-c"],[8,9,"pl-c"]],[[8,62,"pl-c"],[8,9,"pl-c"]],[[8,67,"pl-c"],[8,9,"pl-c"]],[[8,58,"pl-c"],[8,9,"pl-c"]],[[8,58,"pl-c"],[8,9,"pl-c"]],[[8,50,"pl-c"],[8,9,"pl-c"]],[[8,51,"pl-c"],[8,9,"pl-c"]],[[8,62,"pl-c"],[8,9,"pl-c"]],[[8,59,"pl-c"],[8,9,"pl-c"]],[[8,35,"pl-c"],[8,9,"pl-c"]],[[8,36,"pl-c"],[8,9,"pl-c"]],[[8,11,"pl-k"],[37,65,"pl-c"],[37,38,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,16,"pl-en"],[17,21,"pl-smi"],[23,30,"pl-smi"],[32,40,"pl-smi"]],[],[],[[20,48,"pl-c"],[20,21,"pl-c"]],[],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,12,"pl-en"]],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,56,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,25,"pl-en"]],[[2,7,"pl-k"],[8,12,"pl-en"]],[[4,7,"pl-k"],[8,15,"pl-en"],[16,22,"pl-smi"],[24,25,"pl-k"],[25,29,"pl-smi"]],[[6,19,"pl-smi"],[20,21,"pl-k"]],[],[[6,12,"pl-k"],[25,26,"pl-k"],[27,44,"pl-c1"],[45,58,"pl-smi"]],[[8,13,"pl-k"],[14,28,"pl-c1"],[30,96,"pl-s"],[30,31,"pl-pds"],[43,45,"pl-pse"],[45,51,"pl-s1"],[51,52,"pl-pse"],[77,79,"pl-pse"],[79,94,"pl-s1"],[79,83,"pl-c1"],[84,89,"pl-k"],[94,95,"pl-pse"],[95,96,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,21,"pl-smi"],[22,23,"pl-k"],[24,27,"pl-c1"]],[],[[6,28,"pl-c"],[6,7,"pl-c"]],[[34,35,"pl-k"],[41,69,"pl-c"],[41,42,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,71,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,24,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,24,"pl-k"],[24,28,"pl-smi"]],[[18,19,"pl-k"]],[[8,19,"pl-c1"],[20,24,"pl-c1"],[25,30,"pl-k"]],[[8,15,"pl-c1"]],[[8,15,"pl-c1"]],[[8,16,"pl-c1"]],[[8,15,"pl-c1"],[24,30,"pl-c1"]],[[8,15,"pl-c1"]],[[8,13,"pl-c1"]],[],[],[[6,19,"pl-c1"],[21,34,"pl-c1"],[46,82,"pl-s"],[46,47,"pl-pds"],[81,82,"pl-pds"]],[],[[6,19,"pl-c1"],[21,34,"pl-c1"],[46,80,"pl-s"],[46,47,"pl-pds"],[79,80,"pl-pds"],[95,97,"pl-k"],[99,106,"pl-smi"]],[[8,13,"pl-k"]],[[10,54,"pl-c"],[10,11,"pl-c"]],[[17,18,"pl-k"],[19,24,"pl-k"],[25,53,"pl-c"],[25,26,"pl-c"]],[[18,25,"pl-c1"],[27,28,"pl-k"]],[],[[8,14,"pl-k"]],[],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,62,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,15,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,24,"pl-k"],[24,28,"pl-smi"]],[[6,11,"pl-k"],[12,40,"pl-c"],[12,13,"pl-c"]],[[4,10,"pl-k"],[11,20,"pl-c1"]],[[18,60,"pl-s"],[18,19,"pl-pds"],[59,60,"pl-pds"],[62,65,"pl-k"]],[[37,39,"pl-k"],[40,45,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,61,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,25,"pl-en"]],[[2,35,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,84,"pl-c"],[2,3,"pl-c"]],[[2,84,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,27,"pl-c"],[2,3,"pl-c"]],[[2,28,"pl-c"],[2,3,"pl-c"]],[[2,33,"pl-c"],[2,3,"pl-c"]],[[2,9,"pl-c"],[2,3,"pl-c"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,24,"pl-k"],[24,28,"pl-smi"]],[[20,35,"pl-c1"],[37,39,"pl-k"]],[[8,52,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-k"],[14,42,"pl-c"],[14,15,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,65,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,24,"pl-k"]],[[6,10,"pl-c1"],[19,20,"pl-k"],[41,42,"pl-k"],[42,46,"pl-c1"]],[[6,11,"pl-k"],[12,40,"pl-c"],[12,13,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,56,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,25,"pl-en"]],[[2,7,"pl-k"],[8,12,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,34,"pl-smi"],[36,37,"pl-k"],[37,41,"pl-smi"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,86,"pl-c"],[6,7,"pl-c"]],[[31,32,"pl-k"]],[[4,7,"pl-k"]],[],[[4,9,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,77,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,28,"pl-en"]],[[4,7,"pl-k"],[8,19,"pl-en"],[20,26,"pl-smi"],[28,29,"pl-k"],[29,33,"pl-smi"]],[[6,76,"pl-c"],[6,7,"pl-c"]],[[6,54,"pl-c"],[6,7,"pl-c"]],[[6,65,"pl-c"],[6,7,"pl-c"]],[[8,9,"pl-k"],[10,15,"pl-k"]],[[6,44,"pl-c"],[6,7,"pl-c"]],[[29,35,"pl-k"],[49,90,"pl-c"],[49,50,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,51,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,20,"pl-en"],[23,44,"pl-e"],[23,44,"pl-en"]],[[2,80,"pl-c"],[2,3,"pl-c"]],[[2,5,"pl-k"],[6,11,"pl-en"]],[[4,136,"pl-c"],[4,5,"pl-c"]],[[4,41,"pl-c"],[4,5,"pl-c"]],[[4,10,"pl-smi"],[11,12,"pl-k"],[13,17,"pl-c1"],[28,31,"pl-c1"],[33,38,"pl-c1"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[1,4,"pl-ent"],[5,10,"pl-e"],[11,22,"pl-s"],[11,12,"pl-pds"],[21,22,"pl-pds"]],[[3,5,"pl-ent"],[6,11,"pl-e"],[12,35,"pl-s"],[12,13,"pl-pds"],[34,35,"pl-pds"]],[],[],[[4,6,"pl-ent"]],[[2,5,"pl-ent"]],[[0,3,"pl-s"]],[],[[0,15,"pl-mh"],[4,15,"pl-en"]],[[13,14,"pl-s"],[14,64,"pl-c1"],[64,65,"pl-s"],[84,85,"pl-s"],[85,99,"pl-c1"],[99,100,"pl-s"]],[],[[9,10,"pl-s"],[10,30,"pl-c1"],[30,31,"pl-s"],[66,67,"pl-s"],[67,81,"pl-c1"],[81,82,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,72,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,68,"pl-c"],[2,3,"pl-c"]],[[2,74,"pl-c"],[2,3,"pl-c"]],[[2,8,"pl-k"],[9,23,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,24,"pl-k"],[24,28,"pl-smi"]],[[6,40,"pl-c"],[6,7,"pl-c"]],[[6,8,"pl-k"],[44,53,"pl-c1"],[55,64,"pl-c1"]],[[8,95,"pl-c"],[8,9,"pl-c"]],[[15,16,"pl-k"],[22,55,"pl-c"],[22,23,"pl-c"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-k"]],[[20,106,"pl-s"],[20,21,"pl-pds"],[43,45,"pl-pse"],[45,60,"pl-s1"],[45,49,"pl-c1"],[50,55,"pl-k"],[60,61,"pl-pse"],[61,63,"pl-cce"],[63,65,"pl-pse"],[65,76,"pl-s1"],[76,77,"pl-pse"],[105,106,"pl-pds"],[107,109,"pl-k"]],[[8,13,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,58,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,7,"pl-k"],[8,21,"pl-en"]],[[4,10,"pl-k"],[11,20,"pl-en"]],[[6,57,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,17,"pl-en"],[18,22,"pl-smi"],[24,32,"pl-smi"],[33,34,"pl-k"],[39,46,"pl-smi"],[47,48,"pl-k"],[49,54,"pl-c1"],[56,60,"pl-smi"],[61,62,"pl-k"],[67,69,"pl-k"]],[[8,19,"pl-smi"],[28,29,"pl-k"]],[[6,9,"pl-k"]],[[6,11,"pl-k"],[12,29,"pl-c1"],[30,38,"pl-c1"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,71,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,24,"pl-en"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,16,"pl-k"],[16,20,"pl-smi"]],[[20,21,"pl-k"],[22,25,"pl-c1"]],[[6,10,"pl-c1"],[24,25,"pl-k"],[47,49,"pl-k"]],[[8,17,"pl-c1"]],[[10,55,"pl-c"],[10,11,"pl-c"]],[[24,25,"pl-k"],[26,31,"pl-k"],[32,56,"pl-c"],[32,33,"pl-c"]],[],[[6,9,"pl-k"]],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,65,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,78,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,16,"pl-k"],[16,20,"pl-smi"]],[[6,11,"pl-k"],[14,32,"pl-c1"],[34,51,"pl-c1"],[52,54,"pl-k"]],[[6,11,"pl-k"],[12,35,"pl-c"],[12,13,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,61,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,25,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,73,"pl-c"],[4,5,"pl-c"]],[[4,55,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,16,"pl-k"],[16,20,"pl-smi"],[22,23,"pl-k"],[23,28,"pl-smi"]],[[14,15,"pl-k"],[16,33,"pl-c1"],[34,35,"pl-k"],[41,42,"pl-k"]],[],[[20,21,"pl-k"],[46,74,"pl-c"],[46,47,"pl-c"]],[],[[6,8,"pl-k"],[17,22,"pl-c1"]],[[8,30,"pl-c1"]],[[6,10,"pl-k"]],[[8,34,"pl-c1"]],[[6,9,"pl-k"]],[],[[6,10,"pl-c1"],[25,26,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,65,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,30,"pl-smi"]],[[6,35,"pl-c1"],[45,47,"pl-k"],[48,53,"pl-k"],[54,100,"pl-c"],[54,55,"pl-c"]],[[4,7,"pl-k"]],[],[[4,58,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,37,"pl-en"],[38,45,"pl-smi"]],[[6,103,"pl-c"],[6,7,"pl-c"]],[[6,76,"pl-c"],[6,7,"pl-c"]],[[6,81,"pl-c"],[6,7,"pl-c"]],[[6,16,"pl-c1"],[22,24,"pl-k"],[26,30,"pl-smi"]],[[8,10,"pl-k"]],[[10,26,"pl-c1"]],[[22,23,"pl-k"],[24,33,"pl-c1"],[34,67,"pl-c1"]],[[10,16,"pl-k"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[6,9,"pl-c1"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,65,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,23,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,30,"pl-smi"],[31,32,"pl-k"]],[[6,11,"pl-k"],[12,14,"pl-k"],[15,36,"pl-c1"],[46,48,"pl-k"],[49,52,"pl-s"],[49,50,"pl-pds"],[51,52,"pl-pds"],[53,78,"pl-c"],[53,54,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,53,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,30,"pl-smi"],[31,32,"pl-k"]],[[6,22,"pl-c1"]],[],[[6,22,"pl-c1"],[32,60,"pl-c"],[32,33,"pl-c"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,24,"pl-en"],[25,32,"pl-smi"]],[[14,15,"pl-k"],[31,39,"pl-c1"]],[[14,15,"pl-k"],[31,39,"pl-c1"]],[],[[14,15,"pl-k"],[29,65,"pl-c"],[29,30,"pl-c"]],[],[[29,31,"pl-k"]],[[37,38,"pl-k"],[39,42,"pl-c1"],[43,45,"pl-k"],[54,62,"pl-c1"]],[[30,31,"pl-k"],[40,42,"pl-k"]],[],[[45,73,"pl-c"],[45,46,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,61,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,7,"pl-k"],[8,16,"pl-en"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,22,"pl-smi"],[24,31,"pl-smi"]],[[6,8,"pl-k"],[22,30,"pl-c1"]],[],[[6,10,"pl-k"]],[[42,70,"pl-c"],[42,43,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,42,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,23,"pl-en"],[24,31,"pl-smi"],[33,40,"pl-smi"]],[[6,22,"pl-c1"],[23,26,"pl-k"],[27,42,"pl-smi"],[69,97,"pl-c"],[69,70,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,70,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,7,"pl-k"],[8,24,"pl-en"],[27,43,"pl-e"],[27,43,"pl-en"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,22,"pl-smi"],[24,31,"pl-smi"]],[[6,11,"pl-smi"],[15,16,"pl-k"]],[[6,14,"pl-smi"],[15,16,"pl-k"]],[[15,16,"pl-k"]],[],[],[],[[6,21,"pl-smi"],[38,41,"pl-k"],[66,68,"pl-k"]],[],[[40,47,"pl-c1"],[58,65,"pl-c1"],[68,96,"pl-c"],[68,69,"pl-c"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,23,"pl-en"],[24,32,"pl-smi"],[34,45,"pl-smi"],[46,47,"pl-k"],[48,51,"pl-c1"],[53,59,"pl-smi"],[60,61,"pl-k"],[62,65,"pl-c1"]],[[19,20,"pl-k"],[21,26,"pl-smi"],[35,37,"pl-k"]],[],[[46,48,"pl-k"],[50,56,"pl-smi"],[58,85,"pl-c"],[58,59,"pl-c"]],[[19,28,"pl-c1"],[30,41,"pl-c1"],[63,70,"pl-c1"],[82,95,"pl-c1"],[98,100,"pl-k"]],[[10,64,"pl-c"],[10,11,"pl-c"]],[[43,44,"pl-k"],[44,48,"pl-smi"],[55,66,"pl-c1"],[67,68,"pl-k"],[76,103,"pl-c"],[76,77,"pl-c"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,26,"pl-en"],[27,31,"pl-smi"],[33,39,"pl-smi"]],[[14,15,"pl-k"],[21,23,"pl-k"]],[[14,15,"pl-k"],[16,21,"pl-k"]],[],[[6,8,"pl-k"]],[[13,14,"pl-k"],[15,20,"pl-smi"]],[[27,34,"pl-c1"]],[[39,40,"pl-k"],[40,44,"pl-smi"],[51,62,"pl-c1"],[63,64,"pl-k"]],[[6,10,"pl-k"]],[],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,52,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,7,"pl-k"],[8,16,"pl-en"]],[[4,7,"pl-k"],[8,14,"pl-en"],[15,19,"pl-smi"],[21,27,"pl-smi"],[29,35,"pl-smi"],[36,37,"pl-k"],[38,41,"pl-c1"],[43,44,"pl-k"],[44,49,"pl-smi"]],[[33,35,"pl-k"]],[[8,58,"pl-c"],[8,9,"pl-c"]],[[8,86,"pl-c"],[8,9,"pl-c"]],[[8,58,"pl-c"],[8,9,"pl-c"]],[[8,18,"pl-c"],[8,9,"pl-c"]],[],[[8,145,"pl-c"],[8,9,"pl-c"]],[[8,199,"pl-c"],[8,9,"pl-c"]],[[8,67,"pl-c"],[8,9,"pl-c"]],[[47,48,"pl-k"]],[[6,9,"pl-k"]],[[4,10,"pl-k"]],[],[[4,7,"pl-k"]],[],[[4,68,"pl-c"],[4,5,"pl-c"]],[[4,60,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,16,"pl-en"],[17,21,"pl-smi"]],[[6,12,"pl-k"],[13,15,"pl-k"],[16,25,"pl-smi"]],[],[[6,67,"pl-c"],[6,7,"pl-c"]],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,23,"pl-c"],[6,7,"pl-c"]],[[6,20,"pl-smi"],[33,35,"pl-k"]],[[8,76,"pl-c"],[8,9,"pl-c"]],[[8,73,"pl-c"],[8,9,"pl-c"]],[[8,24,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-k"],[15,17,"pl-k"],[18,27,"pl-smi"]],[],[[8,10,"pl-k"],[22,32,"pl-c1"],[34,51,"pl-c1"]],[[14,15,"pl-k"],[16,26,"pl-c1"],[28,45,"pl-c1"]],[[8,12,"pl-k"]],[[14,15,"pl-k"]],[[8,11,"pl-k"]],[],[[19,38,"pl-s"],[19,20,"pl-pds"],[37,38,"pl-pds"],[40,42,"pl-k"]],[[23,51,"pl-c"],[23,24,"pl-c"]],[[8,11,"pl-k"]],[],[[8,65,"pl-c"],[8,9,"pl-c"]],[[8,45,"pl-c"],[8,9,"pl-c"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,21,"pl-c1"],[22,24,"pl-k"],[25,38,"pl-smi"]],[[8,17,"pl-smi"],[18,19,"pl-k"],[20,24,"pl-c1"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,15,"pl-en"],[16,19,"pl-smi"]],[],[[6,75,"pl-c"],[6,7,"pl-c"]],[[11,12,"pl-k"],[13,21,"pl-smi"],[27,31,"pl-c1"],[33,61,"pl-c"],[33,34,"pl-c"]],[],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,28,"pl-c"],[6,7,"pl-c"]],[[13,14,"pl-k"],[15,29,"pl-s"],[15,25,"pl-pds"]],[[0,56,"pl-s"],[12,14,"pl-pse"],[14,25,"pl-s1"],[25,26,"pl-pse"]],[[0,143,"pl-s"],[60,62,"pl-pse"],[62,83,"pl-s1"],[62,75,"pl-smi"],[83,84,"pl-pse"],[121,123,"pl-pse"],[123,134,"pl-s1"],[134,135,"pl-pse"],[136,138,"pl-pse"],[138,142,"pl-s1"],[142,143,"pl-pse"]],[[0,14,"pl-s"]],[[0,79,"pl-s"]],[[0,11,"pl-s"]],[[0,13,"pl-s"],[0,13,"pl-pds"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[6,120,"pl-c"],[6,7,"pl-c"]],[[6,121,"pl-c"],[6,7,"pl-c"]],[[6,84,"pl-c"],[6,7,"pl-c"]],[[6,72,"pl-c"],[6,7,"pl-c"]],[[6,57,"pl-c"],[6,7,"pl-c"]],[[6,34,"pl-c"],[6,7,"pl-c"]],[[6,75,"pl-c"],[6,7,"pl-c"]],[[6,60,"pl-c"],[6,7,"pl-c"]],[[6,54,"pl-c"],[6,7,"pl-c"]],[[6,28,"pl-c"],[6,7,"pl-c"]],[[6,27,"pl-c"],[6,7,"pl-c"]],[[6,30,"pl-c"],[6,7,"pl-c"]],[[6,40,"pl-c"],[6,7,"pl-c"]],[[6,25,"pl-c"],[6,7,"pl-c"]],[[6,90,"pl-c"],[6,7,"pl-c"]],[[6,22,"pl-c"],[6,7,"pl-c"]],[[42,43,"pl-c1"],[45,158,"pl-c"],[45,46,"pl-c"]],[[6,42,"pl-c"],[6,7,"pl-c"]],[[6,17,"pl-c1"],[35,39,"pl-c1"],[41,50,"pl-c1"]],[[4,7,"pl-k"]],[],[[0,69,"pl-c"],[0,1,"pl-c"]],[[4,10,"pl-k"],[11,19,"pl-en"]],[[6,11,"pl-k"],[12,15,"pl-en"]],[[8,11,"pl-k"],[12,16,"pl-en"],[17,25,"pl-smi"]],[[26,27,"pl-k"],[63,71,"pl-c1"],[73,83,"pl-c1"]],[],[[14,15,"pl-k"],[32,36,"pl-c1"],[37,49,"pl-c1"],[51,53,"pl-s"],[51,52,"pl-pds"],[52,53,"pl-pds"]],[[19,20,"pl-k"],[21,23,"pl-smi"]],[],[],[],[[10,71,"pl-c"],[10,11,"pl-c"]],[],[],[[10,14,"pl-c1"],[15,20,"pl-k"]],[],[[12,19,"pl-c1"],[21,25,"pl-c1"],[26,31,"pl-k"]],[[12,17,"pl-c1"],[19,23,"pl-c1"],[24,29,"pl-k"],[44,46,"pl-k"],[47,50,"pl-s"],[47,48,"pl-pds"],[49,50,"pl-pds"]],[],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,78,"pl-mh"],[4,78,"pl-en"]],[],[],[[32,33,"pl-s"],[33,39,"pl-c1"],[39,40,"pl-s"],[52,53,"pl-s"],[53,67,"pl-c1"],[67,68,"pl-s"],[84,85,"pl-s"],[85,116,"pl-c1"],[116,117,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,54,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,8,"pl-k"],[9,18,"pl-en"]],[[4,7,"pl-k"],[8,20,"pl-en"]],[[6,61,"pl-c"],[6,7,"pl-c"]],[[25,28,"pl-k"],[30,64,"pl-c"],[30,31,"pl-c"]],[],[[22,125,"pl-c"],[22,23,"pl-c"]],[[8,12,"pl-c1"]],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[6,50,"pl-c"],[6,7,"pl-c"]],[[21,22,"pl-k"],[23,39,"pl-c1"]],[[6,128,"pl-c"],[6,7,"pl-c"]],[[21,22,"pl-k"]],[],[[27,28,"pl-smi"]],[[10,11,"pl-k"],[46,50,"pl-smi"],[52,56,"pl-smi"]],[[24,25,"pl-c1"],[41,42,"pl-k"]],[],[],[[6,109,"pl-c"],[6,7,"pl-c"]],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,26,"pl-en"]],[[6,51,"pl-c"],[6,7,"pl-c"]],[[6,26,"pl-smi"],[27,30,"pl-k"],[31,35,"pl-c1"],[36,41,"pl-k"]],[[4,7,"pl-k"]],[],[[4,132,"pl-c"],[4,5,"pl-c"]],[[4,106,"pl-c"],[4,5,"pl-c"]],[[4,66,"pl-c"],[4,5,"pl-c"]],[[4,10,"pl-k"],[11,23,"pl-en"]],[[6,9,"pl-k"],[10,28,"pl-en"]],[[8,30,"pl-c"],[8,9,"pl-c"]],[[8,27,"pl-smi"],[28,31,"pl-k"],[32,37,"pl-k"]],[[24,25,"pl-k"]],[[18,19,"pl-k"],[32,40,"pl-c1"],[43,45,"pl-k"],[46,53,"pl-c1"]],[[18,19,"pl-k"],[32,41,"pl-c1"],[43,45,"pl-k"],[46,54,"pl-c1"]],[],[[10,15,"pl-c1"],[16,19,"pl-k"],[20,30,"pl-c1"],[32,36,"pl-c1"],[38,40,"pl-k"]],[[12,14,"pl-k"]],[[14,21,"pl-k"]],[[14,21,"pl-k"]],[[12,15,"pl-k"]],[],[[12,14,"pl-k"]],[[14,21,"pl-k"]],[[12,15,"pl-k"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,49,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,17,"pl-en"]],[[2,7,"pl-k"],[8,12,"pl-en"]],[[4,7,"pl-k"],[8,18,"pl-en"],[19,26,"pl-smi"],[27,28,"pl-k"],[29,32,"pl-c1"],[34,41,"pl-smi"],[42,43,"pl-k"],[48,58,"pl-smi"],[59,60,"pl-k"],[61,64,"pl-c1"],[66,73,"pl-smi"],[74,75,"pl-k"],[76,79,"pl-c1"]],[[6,14,"pl-smi"],[15,16,"pl-k"],[17,30,"pl-c1"],[32,50,"pl-c1"],[51,54,"pl-k"]],[],[[6,8,"pl-k"],[23,33,"pl-c1"],[35,43,"pl-c1"]],[[8,22,"pl-smi"],[23,24,"pl-k"]],[[6,10,"pl-k"]],[[23,24,"pl-k"],[39,49,"pl-c1"],[51,64,"pl-c1"],[66,67,"pl-k"]],[[20,30,"pl-c1"],[32,45,"pl-c1"],[46,49,"pl-k"]],[[32,33,"pl-k"],[42,44,"pl-k"]],[[32,33,"pl-k"],[45,54,"pl-c1"],[55,57,"pl-k"]],[[8,22,"pl-smi"],[23,24,"pl-k"],[25,35,"pl-c1"],[37,45,"pl-c1"],[46,49,"pl-k"]],[[6,9,"pl-k"]],[],[[6,16,"pl-smi"],[17,18,"pl-k"]],[],[[22,50,"pl-c"],[22,23,"pl-c"]],[],[],[[6,22,"pl-c1"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,14,"pl-en"],[15,26,"pl-smi"]],[[6,15,"pl-smi"],[16,17,"pl-k"]],[[25,27,"pl-k"],[29,32,"pl-smi"],[34,39,"pl-smi"]],[[10,98,"pl-c"],[10,11,"pl-c"]],[[32,41,"pl-s"],[32,33,"pl-pds"],[34,36,"pl-pse"],[36,39,"pl-s1"],[39,40,"pl-pse"],[40,41,"pl-pds"]],[[8,11,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,3,"pl-s"]],[],[],[[0,41,"pl-mh"],[3,41,"pl-en"],[21,22,"pl-s"],[22,36,"pl-c1"],[36,37,"pl-s"]],[],[[22,23,"pl-s"],[23,37,"pl-c1"],[37,38,"pl-s"]],[],[[12,13,"pl-s"],[13,18,"pl-c1"],[18,19,"pl-s"],[31,32,"pl-s"],[32,38,"pl-c1"],[38,39,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,19,"pl-c"],[0,1,"pl-c"]],[[0,8,"pl-c1"],[9,10,"pl-k"],[11,15,"pl-c1"],[28,51,"pl-s"],[28,29,"pl-pds"],[50,51,"pl-pds"],[53,60,"pl-c1"]],[],[[0,16,"pl-k"],[17,33,"pl-s"],[17,18,"pl-pds"],[32,33,"pl-pds"]],[[0,7,"pl-k"],[8,24,"pl-s"],[8,9,"pl-pds"],[23,24,"pl-pds"],[25,51,"pl-c"],[25,26,"pl-c"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,7,"pl-k"],[8,23,"pl-s"],[8,9,"pl-pds"],[22,23,"pl-pds"]],[],[[8,9,"pl-k"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,20,"pl-s"],[10,11,"pl-pds"],[19,20,"pl-pds"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,19,"pl-s"],[10,11,"pl-pds"],[18,19,"pl-pds"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,19,"pl-s"],[10,11,"pl-pds"],[18,19,"pl-pds"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,18,"pl-s"],[10,11,"pl-pds"],[17,18,"pl-pds"]],[[2,6,"pl-s"],[2,3,"pl-pds"],[5,6,"pl-pds"],[10,21,"pl-s"],[10,11,"pl-pds"],[20,21,"pl-pds"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,18,"pl-s"],[10,11,"pl-pds"],[17,18,"pl-pds"]],[[2,5,"pl-s"],[2,3,"pl-pds"],[4,5,"pl-pds"],[10,16,"pl-s"],[10,11,"pl-pds"],[15,16,"pl-pds"]],[],[],[[8,9,"pl-k"],[10,14,"pl-c1"]],[[8,9,"pl-k"],[27,29,"pl-k"],[38,59,"pl-c"],[38,39,"pl-c"]],[],[[0,5,"pl-c1"],[7,14,"pl-c1"],[31,35,"pl-c1"],[36,64,"pl-c"],[36,37,"pl-c"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,39,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[13,17,"pl-smi"]],[[6,9,"pl-k"],[10,16,"pl-en"],[17,31,"pl-smi"],[33,37,"pl-smi"],[38,39,"pl-k"],[44,46,"pl-k"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,34,"pl-c"],[8,9,"pl-c"]],[[8,69,"pl-c"],[8,9,"pl-c"]],[[8,48,"pl-c"],[8,9,"pl-c"]],[[16,17,"pl-k"]],[],[[8,82,"pl-c"],[8,9,"pl-c"]],[],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,67,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,58,"pl-c"],[4,5,"pl-c"]],[[4,9,"pl-k"],[10,23,"pl-en"],[26,30,"pl-e"],[26,30,"pl-en"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,8,"pl-mh"],[4,8,"pl-en"]],[],[],[[0,1,"pl-s"],[1,33,"pl-corl"],[33,34,"pl-s"],[34,35,"pl-s"],[35,67,"pl-corl"],[67,68,"pl-s"]],[],[[26,27,"pl-s"],[27,86,"pl-c1"],[86,87,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,49,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,14,"pl-en"],[17,21,"pl-e"],[17,21,"pl-en"]],[[6,11,"pl-k"],[15,19,"pl-smi"]],[[8,27,"pl-c"],[8,9,"pl-c"]],[[8,11,"pl-k"],[12,19,"pl-en"],[20,27,"pl-smi"],[29,33,"pl-smi"],[35,41,"pl-smi"]],[[10,14,"pl-c"],[10,11,"pl-c"]],[[38,41,"pl-c1"],[51,66,"pl-c"],[51,52,"pl-c"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,32,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,10,"pl-en"]],[[2,7,"pl-k"],[11,15,"pl-smi"]],[[4,22,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,16,"pl-en"],[17,21,"pl-smi"],[23,33,"pl-smi"],[35,45,"pl-smi"],[47,53,"pl-smi"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[6,56,"pl-c"],[6,7,"pl-c"]],[[15,16,"pl-k"],[17,20,"pl-k"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,64,"pl-c"],[6,7,"pl-c"]],[[6,74,"pl-c"],[6,7,"pl-c"]],[[48,50,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,43,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,10,"pl-en"]],[[2,41,"pl-c"],[2,3,"pl-c"]],[[2,60,"pl-c"],[2,3,"pl-c"]],[[2,8,"pl-k"],[9,19,"pl-en"]],[[4,7,"pl-k"],[8,22,"pl-en"],[23,30,"pl-smi"],[32,33,"pl-k"],[33,37,"pl-smi"],[39,77,"pl-c"],[39,40,"pl-c"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,74,"pl-c"],[6,7,"pl-c"]],[[18,22,"pl-c1"],[24,25,"pl-k"],[25,29,"pl-smi"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,10,"pl-en"]],[[2,7,"pl-k"],[8,15,"pl-en"],[18,28,"pl-e"],[18,24,"pl-en"],[29,34,"pl-c1"],[36,48,"pl-c1"],[50,67,"pl-c1"],[69,75,"pl-c1"],[77,85,"pl-c1"],[87,101,"pl-c1"]],[[4,7,"pl-k"],[8,11,"pl-en"],[12,20,"pl-smi"],[22,26,"pl-smi"],[27,28,"pl-k"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,22,"pl-c"],[6,7,"pl-c"]],[[6,68,"pl-c"],[6,7,"pl-c"]],[[6,92,"pl-c"],[6,7,"pl-c"]],[[6,80,"pl-c"],[6,7,"pl-c"]],[[15,23,"pl-c1"],[30,31,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,32,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,10,"pl-en"]],[[2,7,"pl-c"],[2,3,"pl-c"]],[[2,9,"pl-k"],[10,14,"pl-c1"],[16,20,"pl-c1"],[21,76,"pl-c"],[21,22,"pl-c"]],[[0,3,"pl-k"]],[],[[0,37,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,8,"pl-k"],[9,13,"pl-en"]],[[4,9,"pl-k"],[13,17,"pl-smi"]],[[6,38,"pl-c"],[6,7,"pl-c"]],[[6,77,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,18,"pl-en"],[19,23,"pl-smi"]],[[8,20,"pl-c"],[8,9,"pl-c"]],[[8,54,"pl-c"],[8,9,"pl-c"]],[[13,19,"pl-k"],[20,32,"pl-c1"]],[[8,65,"pl-c"],[8,9,"pl-c"]],[[8,71,"pl-c"],[8,9,"pl-c"]],[[8,90,"pl-c"],[8,9,"pl-c"]],[[18,26,"pl-c1"],[28,38,"pl-c1"],[39,89,"pl-c"],[39,40,"pl-c"]],[[18,26,"pl-c1"],[28,33,"pl-c1"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,10,"pl-k"],[11,23,"pl-en"]],[[6,42,"pl-c"],[6,7,"pl-c"]],[[6,77,"pl-c"],[6,7,"pl-c"]],[[6,40,"pl-c"],[6,7,"pl-c"]],[[6,78,"pl-c"],[6,7,"pl-c"]],[[6,87,"pl-c"],[6,7,"pl-c"]],[[6,92,"pl-c"],[6,7,"pl-c"]],[[6,80,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,22,"pl-en"],[23,27,"pl-smi"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,54,"pl-c"],[8,9,"pl-c"]],[[29,76,"pl-c"],[29,30,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,49,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,73,"pl-c"],[4,5,"pl-c"]],[[4,10,"pl-k"],[11,15,"pl-en"]],[[6,11,"pl-k"],[15,19,"pl-smi"]],[[8,11,"pl-k"],[12,26,"pl-en"],[27,31,"pl-smi"]],[[10,12,"pl-k"],[18,20,"pl-k"],[21,30,"pl-s"],[21,22,"pl-pds"],[29,30,"pl-pds"]],[[12,80,"pl-c"],[12,13,"pl-c"]],[[12,68,"pl-c"],[12,13,"pl-c"]],[[12,24,"pl-k"],[25,33,"pl-s"],[25,26,"pl-pds"],[32,33,"pl-pds"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,5,"pl-k"],[6,10,"pl-en"]],[[2,7,"pl-k"],[8,15,"pl-en"],[18,28,"pl-e"],[18,24,"pl-en"],[29,34,"pl-c1"],[36,48,"pl-c1"],[50,67,"pl-c1"],[69,75,"pl-c1"],[77,85,"pl-c1"],[87,101,"pl-c1"]],[[4,7,"pl-k"],[8,11,"pl-en"],[12,20,"pl-smi"],[22,26,"pl-smi"],[27,28,"pl-k"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[[6,100,"pl-c"],[6,7,"pl-c"]],[[6,23,"pl-c"],[6,7,"pl-c"]],[[6,56,"pl-c"],[6,7,"pl-c"]],[[6,70,"pl-c"],[6,7,"pl-c"]],[[6,63,"pl-c"],[6,7,"pl-c"]],[[15,23,"pl-c1"],[30,31,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,67,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,9,"pl-k"],[10,23,"pl-en"],[26,30,"pl-e"],[26,30,"pl-en"]],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,17,"pl-en"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-c1"],[15,21,"pl-c1"],[22,25,"pl-k"],[46,48,"pl-k"],[50,56,"pl-smi"]],[[10,67,"pl-c"],[10,11,"pl-c"]],[[10,72,"pl-c"],[10,11,"pl-c"]],[[10,66,"pl-c"],[10,11,"pl-c"]],[[10,55,"pl-c"],[10,11,"pl-c"]],[[10,17,"pl-k"],[18,26,"pl-c1"]],[],[[10,13,"pl-c1"],[20,25,"pl-c1"]],[],[[23,51,"pl-c"],[23,24,"pl-c"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,23,"pl-mh"],[4,23,"pl-en"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,67,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,12,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"],[17,31,"pl-e"],[19,23,"pl-en"],[25,31,"pl-en"]],[[4,7,"pl-k"],[8,13,"pl-en"]],[],[],[[6,10,"pl-c1"],[11,15,"pl-c1"],[17,19,"pl-k"]],[[8,12,"pl-c1"]],[[6,9,"pl-k"]],[],[],[],[],[[6,67,"pl-c"],[6,7,"pl-c"]],[[19,45,"pl-c"],[19,20,"pl-c"]],[],[[6,11,"pl-k"],[12,71,"pl-c"],[12,13,"pl-c"]],[[4,10,"pl-k"]],[[6,10,"pl-c1"],[11,20,"pl-s"],[11,12,"pl-pds"],[19,20,"pl-pds"],[21,27,"pl-k"],[28,36,"pl-smi"],[37,39,"pl-k"],[48,58,"pl-c1"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,21,"pl-en"]],[[6,81,"pl-c"],[6,7,"pl-c"]],[[6,49,"pl-c"],[6,7,"pl-c"]],[[6,59,"pl-c"],[6,7,"pl-c"]],[[6,52,"pl-c"],[6,7,"pl-c"]],[[6,69,"pl-c"],[6,7,"pl-c"]],[[6,73,"pl-c"],[6,7,"pl-c"]],[[18,45,"pl-c"],[18,19,"pl-c"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,7,"pl-k"],[8,19,"pl-en"]],[[6,18,"pl-smi"],[19,22,"pl-k"]],[],[[14,42,"pl-c"],[14,15,"pl-c"]],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,10,"pl-smi"],[11,14,"pl-k"],[49,77,"pl-c"],[49,50,"pl-c"]],[[6,10,"pl-smi"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,41,"pl-en"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,70,"pl-c"],[6,7,"pl-c"]],[[19,20,"pl-k"],[21,25,"pl-c1"],[27,34,"pl-c1"],[46,50,"pl-c1"],[59,66,"pl-c1"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[4,7,"pl-k"]],[],[[4,50,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,13,"pl-en"],[14,15,"pl-k"],[15,18,"pl-smi"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[],[[6,10,"pl-c"],[6,7,"pl-c"]],[],[[6,44,"pl-c"],[6,7,"pl-c"]],[[6,94,"pl-c"],[6,7,"pl-c"]],[[39,40,"pl-k"],[45,107,"pl-c"],[45,46,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,33,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,7,"pl-k"],[8,23,"pl-en"],[8,12,"pl-c1"],[24,30,"pl-smi"],[32,36,"pl-smi"],[37,38,"pl-k"],[39,45,"pl-c1"],[47,54,"pl-c1"],[55,58,"pl-k"]],[[6,27,"pl-c"],[6,7,"pl-c"]],[[14,15,"pl-k"],[18,22,"pl-c1"]],[],[[10,11,"pl-k"]],[],[[6,12,"pl-k"]],[[4,7,"pl-k"]],[],[[4,68,"pl-c"],[4,5,"pl-c"]],[[4,26,"pl-c"],[4,5,"pl-c"]],[[4,46,"pl-c"],[4,5,"pl-c"]],[[4,54,"pl-c"],[4,5,"pl-c"]],[[4,128,"pl-c"],[4,5,"pl-c"]],[[4,51,"pl-c"],[4,5,"pl-c"]],[[4,56,"pl-c"],[4,5,"pl-c"]],[[4,18,"pl-c"],[4,5,"pl-c"]],[[4,78,"pl-c"],[4,5,"pl-c"]],[[4,9,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,28,"pl-en"],[8,12,"pl-c1"],[29,43,"pl-smi"],[45,49,"pl-smi"],[49,50,"pl-k"],[50,60,"pl-s"],[50,51,"pl-pds"],[59,60,"pl-pds"]],[[6,88,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,34,"pl-s"],[11,12,"pl-pds"],[31,33,"pl-cce"],[33,34,"pl-pds"],[35,36,"pl-k"],[52,53,"pl-k"],[54,66,"pl-s"],[54,55,"pl-pds"],[55,57,"pl-cce"],[65,66,"pl-pds"]],[[8,24,"pl-c1"],[32,33,"pl-c1"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[[13,14,"pl-s"],[14,32,"pl-c1"],[32,33,"pl-s"],[44,45,"pl-s"],[45,96,"pl-c1"],[96,97,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,45,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,8,"pl-k"],[9,16,"pl-en"]],[[4,10,"pl-k"],[11,15,"pl-en"]],[[6,55,"pl-c"],[6,7,"pl-c"]],[[6,60,"pl-c"],[6,7,"pl-c"]],[[6,9,"pl-k"],[10,18,"pl-en"],[10,14,"pl-c1"],[19,22,"pl-smi"],[24,31,"pl-smi"],[32,33,"pl-k"]],[[15,16,"pl-k"],[17,21,"pl-c1"]],[],[[8,13,"pl-c"],[8,9,"pl-c"]],[[17,18,"pl-k"],[21,25,"pl-c1"],[27,35,"pl-c1"],[36,39,"pl-k"],[46,53,"pl-c1"]],[],[[8,13,"pl-k"]],[[10,73,"pl-c"],[10,11,"pl-c"]],[[23,51,"pl-c"],[23,24,"pl-c"]],[[8,14,"pl-k"],[15,24,"pl-c1"]],[[10,14,"pl-c1"],[15,70,"pl-s"],[15,16,"pl-pds"],[69,70,"pl-pds"]],[],[[10,14,"pl-c1"],[15,27,"pl-s"],[15,16,"pl-pds"],[26,27,"pl-pds"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,85,"pl-c"],[2,3,"pl-c"]],[[2,90,"pl-c"],[2,3,"pl-c"]],[[2,69,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,80,"pl-c"],[2,3,"pl-c"]],[[2,16,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,16,"pl-en"]],[[4,7,"pl-k"],[8,18,"pl-en"],[19,23,"pl-smi"],[25,38,"pl-smi"],[38,39,"pl-k"]],[[6,13,"pl-smi"],[21,22,"pl-k"],[23,26,"pl-c1"]],[[6,13,"pl-smi"],[21,22,"pl-k"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,8,"pl-k"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,25,"pl-c1"],[26,29,"pl-k"],[30,34,"pl-c1"],[36,43,"pl-smi"]],[[6,10,"pl-k"]],[[8,45,"pl-c"],[8,9,"pl-c"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,24,"pl-c1"],[25,28,"pl-k"],[29,33,"pl-c1"],[35,42,"pl-smi"]],[[6,9,"pl-k"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[],[[6,89,"pl-c"],[6,7,"pl-c"]],[[20,54,"pl-c"],[20,21,"pl-c"]],[],[],[],[[6,13,"pl-smi"],[18,71,"pl-c"],[18,19,"pl-c"]],[],[[6,10,"pl-k"],[11,18,"pl-smi"]],[[6,10,"pl-k"],[11,16,"pl-c1"]],[[12,37,"pl-s"],[12,13,"pl-pds"],[36,37,"pl-pds"]],[[6,10,"pl-k"],[11,15,"pl-c1"],[17,22,"pl-c1"]],[],[[6,10,"pl-k"],[11,19,"pl-c1"]],[[12,29,"pl-s"],[12,13,"pl-pds"],[28,29,"pl-pds"]],[[8,11,"pl-c1"]],[[8,15,"pl-smi"]],[],[[6,10,"pl-k"],[11,16,"pl-c1"]],[[8,17,"pl-c"],[8,9,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,63,"pl-c"],[2,3,"pl-c"]],[[2,74,"pl-c"],[2,3,"pl-c"]],[[2,64,"pl-c"],[2,3,"pl-c"]],[[2,3,"pl-c"],[2,3,"pl-c"]],[[2,76,"pl-c"],[2,3,"pl-c"]],[[2,76,"pl-c"],[2,3,"pl-c"]],[[2,28,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,14,"pl-en"],[17,23,"pl-e"],[17,23,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[14,15,"pl-k"],[23,24,"pl-k"],[38,66,"pl-c"],[38,39,"pl-c"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[13,14,"pl-k"],[26,60,"pl-c"],[26,27,"pl-c"]],[],[[6,57,"pl-c"],[6,7,"pl-c"]],[[6,85,"pl-c"],[6,7,"pl-c"]],[[6,47,"pl-c"],[6,7,"pl-c"]],[[6,65,"pl-c"],[6,7,"pl-c"]],[[6,61,"pl-c"],[6,7,"pl-c"]],[],[],[[6,105,"pl-c"],[6,7,"pl-c"]],[[6,91,"pl-c"],[6,7,"pl-c"]],[[6,104,"pl-c"],[6,7,"pl-c"]],[[6,79,"pl-c"],[6,7,"pl-c"]],[[6,108,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,53,"pl-s"],[11,12,"pl-pds"],[52,53,"pl-pds"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,71,"pl-c"],[2,3,"pl-c"]],[[2,74,"pl-c"],[2,3,"pl-c"]],[[2,29,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,10,"pl-smi"],[11,14,"pl-k"],[15,24,"pl-smi"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[12,13,"pl-k"],[14,22,"pl-smi"],[23,35,"pl-c1"]],[[12,13,"pl-k"],[14,22,"pl-smi"],[23,35,"pl-c1"]],[],[[13,14,"pl-k"],[15,19,"pl-c1"],[21,27,"pl-c1"],[28,31,"pl-k"],[37,46,"pl-smi"],[55,63,"pl-smi"]],[[25,26,"pl-k"]],[[25,26,"pl-k"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"],[12,22,"pl-smi"],[22,23,"pl-k"],[23,27,"pl-c1"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[14,15,"pl-k"],[16,20,"pl-c1"]],[[21,22,"pl-k"],[23,38,"pl-smi"]],[],[[6,31,"pl-c"],[6,7,"pl-c"]],[[6,108,"pl-c"],[6,7,"pl-c"]],[[6,82,"pl-c"],[6,7,"pl-c"]],[[6,71,"pl-c"],[6,7,"pl-c"]],[[6,18,"pl-smi"],[19,20,"pl-k"],[21,31,"pl-c1"],[32,35,"pl-k"],[36,48,"pl-smi"]],[[36,48,"pl-smi"]],[[36,44,"pl-c1"],[46,48,"pl-k"],[50,56,"pl-smi"],[58,64,"pl-smi"]],[],[[8,47,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-c1"],[23,37,"pl-c1"],[39,40,"pl-k"],[41,45,"pl-c1"]],[],[[20,21,"pl-k"],[22,27,"pl-c1"]],[],[[8,10,"pl-k"]],[[22,23,"pl-k"]],[[8,11,"pl-k"]],[],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,10,"pl-k"]],[[10,71,"pl-c"],[10,11,"pl-c"]],[[10,80,"pl-c"],[10,11,"pl-c"]],[[10,58,"pl-c"],[10,11,"pl-c"]],[],[[8,12,"pl-k"]],[[29,48,"pl-smi"]],[[10,18,"pl-smi"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[6,8,"pl-k"],[20,57,"pl-c"],[20,21,"pl-c"]],[[8,33,"pl-c"],[8,9,"pl-c"]],[[8,46,"pl-c"],[8,9,"pl-c"]],[[8,83,"pl-c"],[8,9,"pl-c"]],[[8,111,"pl-c"],[8,9,"pl-c"]],[[8,85,"pl-c"],[8,9,"pl-c"]],[[8,73,"pl-c"],[8,9,"pl-c"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,24,"pl-c1"],[25,28,"pl-k"],[48,95,"pl-c"],[48,49,"pl-c"]],[[8,14,"pl-k"],[15,22,"pl-smi"]],[[6,10,"pl-k"]],[],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,22,"pl-en"]],[[14,15,"pl-k"],[24,25,"pl-k"],[26,33,"pl-smi"]],[[11,12,"pl-k"],[13,25,"pl-smi"]],[[21,22,"pl-k"],[23,38,"pl-smi"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[6,95,"pl-c"],[6,7,"pl-c"]],[[6,75,"pl-c"],[6,7,"pl-c"]],[[6,11,"pl-k"],[12,19,"pl-smi"],[20,22,"pl-k"],[23,27,"pl-c1"]],[[8,13,"pl-k"]],[[10,80,"pl-c"],[10,11,"pl-c"]],[[10,53,"pl-c"],[10,11,"pl-c"]],[[10,79,"pl-c"],[10,11,"pl-c"]],[[14,15,"pl-k"],[16,18,"pl-c1"],[19,25,"pl-c1"]],[],[[25,27,"pl-k"],[29,33,"pl-smi"]],[[12,14,"pl-k"],[20,22,"pl-k"]],[[14,19,"pl-k"],[20,22,"pl-k"]],[[12,16,"pl-k"]],[[14,16,"pl-k"],[20,21,"pl-k"]],[[16,82,"pl-c"],[16,17,"pl-c"]],[[23,24,"pl-k"],[25,31,"pl-c1"],[32,35,"pl-k"],[40,47,"pl-smi"]],[],[[16,21,"pl-c"],[16,17,"pl-c"]],[],[[16,52,"pl-c"],[16,17,"pl-c"]],[[16,64,"pl-c"],[16,17,"pl-c"]],[[16,77,"pl-c"],[16,17,"pl-c"]],[[21,23,"pl-k"],[31,59,"pl-c"],[31,32,"pl-c"]],[],[[41,75,"pl-c"],[41,42,"pl-c"]],[[14,17,"pl-k"]],[[12,15,"pl-k"]],[[10,13,"pl-k"]],[[8,14,"pl-k"],[15,21,"pl-c1"]],[[10,17,"pl-smi"],[32,36,"pl-c1"],[41,54,"pl-s"],[41,42,"pl-pds"],[53,54,"pl-pds"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,43,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,18,"pl-en"]],[[4,62,"pl-c"],[4,5,"pl-c"]],[[4,18,"pl-c"],[4,5,"pl-c"]],[[4,5,"pl-c"],[4,5,"pl-c"]],[[4,65,"pl-c"],[4,5,"pl-c"]],[[4,13,"pl-c"],[4,5,"pl-c"]],[[4,5,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,18,"pl-en"],[19,22,"pl-smi"],[24,27,"pl-smi"],[29,30,"pl-k"],[30,35,"pl-smi"],[37,38,"pl-k"],[38,43,"pl-smi"]],[[6,9,"pl-c"],[6,7,"pl-c"]],[[6,12,"pl-smi"],[13,14,"pl-k"],[15,20,"pl-c1"],[21,24,"pl-k"]],[[6,11,"pl-smi"],[12,13,"pl-k"],[17,109,"pl-c"],[17,18,"pl-c"]],[[6,14,"pl-smi"],[15,16,"pl-k"],[17,18,"pl-c1"],[19,50,"pl-c"],[19,20,"pl-c"]],[[6,10,"pl-smi"],[11,12,"pl-k"],[13,20,"pl-c1"],[26,46,"pl-c"],[26,27,"pl-c"]],[[6,10,"pl-smi"],[11,12,"pl-k"],[13,20,"pl-c1"],[26,46,"pl-c"],[26,27,"pl-c"]],[[6,12,"pl-smi"],[13,14,"pl-k"],[21,96,"pl-c"],[21,22,"pl-c"]],[[6,14,"pl-smi"],[15,16,"pl-k"]],[[6,13,"pl-smi"],[14,15,"pl-k"],[16,19,"pl-c1"]],[],[[6,12,"pl-smi"],[25,27,"pl-k"]],[[8,12,"pl-smi"],[36,69,"pl-c"],[36,37,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[6,14,"pl-smi"],[15,17,"pl-k"],[18,19,"pl-c1"]],[],[[6,32,"pl-c"],[6,7,"pl-c"]],[[6,114,"pl-c"],[6,7,"pl-c"]],[[9,10,"pl-k"],[11,17,"pl-c1"],[18,21,"pl-k"],[22,30,"pl-smi"],[32,34,"pl-k"],[36,43,"pl-smi"]],[[8,40,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-c1"],[28,29,"pl-k"],[30,41,"pl-s"],[30,31,"pl-pds"],[40,41,"pl-pds"],[42,43,"pl-k"],[52,54,"pl-k"],[55,61,"pl-c1"],[82,88,"pl-c1"]],[[14,15,"pl-k"],[16,22,"pl-smi"]],[[14,15,"pl-k"],[16,22,"pl-smi"]],[[8,12,"pl-c"],[8,9,"pl-c"]],[],[[14,15,"pl-k"],[16,22,"pl-smi"],[30,31,"pl-smi"],[35,38,"pl-k"]],[],[[8,33,"pl-c"],[8,9,"pl-c"]],[[8,62,"pl-c"],[8,9,"pl-c"]],[[8,62,"pl-c"],[8,9,"pl-c"]],[[8,55,"pl-c"],[8,9,"pl-c"]],[[8,79,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-k"],[14,18,"pl-c1"]],[[15,16,"pl-k"],[17,20,"pl-c1"]],[],[[19,20,"pl-k"],[21,25,"pl-c1"]],[],[[28,30,"pl-k"]],[[12,17,"pl-k"]],[[14,16,"pl-k"],[17,32,"pl-smi"],[33,34,"pl-k"],[35,36,"pl-c1"]],[[16,31,"pl-smi"],[32,34,"pl-k"],[35,36,"pl-c1"]],[[25,26,"pl-k"],[27,32,"pl-c1"]],[],[[16,21,"pl-k"]],[[14,17,"pl-k"]],[],[[14,16,"pl-k"],[17,26,"pl-smi"]],[[25,26,"pl-k"],[27,32,"pl-c1"]],[[16,21,"pl-k"]],[[14,17,"pl-k"]],[],[[14,22,"pl-smi"],[23,25,"pl-k"],[26,27,"pl-c1"],[28,70,"pl-c"],[28,29,"pl-c"]],[],[],[[14,59,"pl-c"],[14,15,"pl-c"]],[[14,85,"pl-c"],[14,15,"pl-c"]],[[14,91,"pl-c"],[14,15,"pl-c"]],[[14,63,"pl-c"],[14,15,"pl-c"]],[[14,101,"pl-c"],[14,15,"pl-c"]],[[14,73,"pl-c"],[14,15,"pl-c"]],[[14,71,"pl-c"],[14,15,"pl-c"]],[],[],[[14,22,"pl-smi"],[23,25,"pl-k"],[26,27,"pl-c1"]],[[12,15,"pl-k"]],[],[[12,101,"pl-c"],[12,13,"pl-c"]],[[17,18,"pl-k"],[30,32,"pl-k"]],[[10,13,"pl-k"]],[],[[10,15,"pl-k"],[16,22,"pl-k"]],[],[[10,12,"pl-k"],[13,33,"pl-smi"]],[[12,22,"pl-c1"]],[[10,13,"pl-k"]],[],[[10,15,"pl-k"]],[[12,76,"pl-c"],[12,13,"pl-c"]],[[12,65,"pl-c"],[12,13,"pl-c"]],[[12,57,"pl-c"],[12,13,"pl-c"]],[[12,57,"pl-c"],[12,13,"pl-c"]],[[12,83,"pl-c"],[12,13,"pl-c"]],[[12,78,"pl-c"],[12,13,"pl-c"]],[[29,30,"pl-k"]],[[10,16,"pl-k"],[17,26,"pl-c1"]],[[12,18,"pl-c1"],[19,23,"pl-c1"],[24,85,"pl-s"],[24,25,"pl-pds"],[59,61,"pl-pse"],[61,70,"pl-s1"],[70,71,"pl-pse"],[73,75,"pl-pse"],[75,82,"pl-s1"],[77,82,"pl-k"],[82,83,"pl-pse"],[84,85,"pl-pds"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[],[[26,28,"pl-k"]],[[10,18,"pl-smi"],[19,21,"pl-k"],[22,23,"pl-c1"]],[[10,18,"pl-smi"]],[[8,11,"pl-k"]],[[6,9,"pl-k"],[10,34,"pl-c"],[10,11,"pl-c"]],[],[[6,14,"pl-smi"],[15,17,"pl-k"]],[],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,27,"pl-en"]],[[6,12,"pl-smi"],[25,27,"pl-k"]],[[8,13,"pl-k"],[14,18,"pl-c1"]],[[10,16,"pl-k"],[17,19,"pl-k"],[20,29,"pl-smi"]],[],[[10,57,"pl-c"],[10,11,"pl-c"]],[[10,60,"pl-c"],[10,11,"pl-c"]],[[10,57,"pl-c"],[10,11,"pl-c"]],[[10,46,"pl-c"],[10,11,"pl-c"]],[[10,16,"pl-k"],[17,19,"pl-k"],[20,25,"pl-smi"],[31,32,"pl-k"],[33,41,"pl-smi"],[42,43,"pl-k"],[44,48,"pl-smi"],[49,50,"pl-k"],[51,59,"pl-smi"]],[],[[10,19,"pl-smi"],[25,31,"pl-smi"]],[[8,11,"pl-k"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,69,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,10,"pl-en"],[11,15,"pl-smi"]],[[6,12,"pl-smi"],[25,27,"pl-k"]],[[8,10,"pl-k"],[11,20,"pl-smi"]],[[10,15,"pl-k"],[16,56,"pl-s"],[16,17,"pl-pds"],[55,56,"pl-pds"]],[[8,11,"pl-k"]],[],[[8,50,"pl-c"],[8,9,"pl-c"]],[[8,63,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-smi"],[14,16,"pl-k"]],[],[[8,10,"pl-k"],[11,19,"pl-smi"],[20,21,"pl-k"],[22,27,"pl-smi"],[33,36,"pl-k"],[37,45,"pl-smi"],[46,47,"pl-k"],[48,52,"pl-smi"]],[[23,68,"pl-c"],[23,24,"pl-c"]],[[8,11,"pl-k"]],[],[[8,60,"pl-c"],[8,9,"pl-c"]],[[8,88,"pl-c"],[8,9,"pl-c"]],[[8,41,"pl-c"],[8,9,"pl-c"]],[[8,21,"pl-c"],[8,9,"pl-c"]],[[8,17,"pl-c"],[8,9,"pl-c"]],[[8,32,"pl-c"],[8,9,"pl-c"]],[[8,18,"pl-c"],[8,9,"pl-c"]],[[8,74,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-c"],[8,9,"pl-c"]],[[8,18,"pl-smi"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,14,"pl-mh"],[4,14,"pl-en"]],[[15,16,"pl-s"],[16,30,"pl-c1"],[30,31,"pl-s"],[45,46,"pl-s"],[46,83,"pl-c1"],[83,84,"pl-s"]],[],[[3,4,"pl-s"],[4,12,"pl-c1"],[12,13,"pl-s"],[20,21,"pl-s"],[21,40,"pl-c1"],[40,41,"pl-s"],[53,54,"pl-s"],[54,72,"pl-c1"],[72,73,"pl-s"]],[],[[10,11,"pl-s"],[11,64,"pl-c1"],[64,65,"pl-s"]],[],[[3,4,"pl-s"],[4,8,"pl-c1"],[8,9,"pl-s"],[53,54,"pl-s"],[54,113,"pl-c1"],[113,114,"pl-s"]],[],[[24,25,"pl-s"],[25,28,"pl-c1"],[28,29,"pl-s"]],[],[],[],[[34,35,"pl-s"],[35,39,"pl-c1"],[39,40,"pl-s"]],[],[[0,16,"pl-mh"],[4,16,"pl-en"]],[[0,23,"pl-mh"],[5,23,"pl-en"]],[],[],[[50,51,"pl-s"],[69,70,"pl-s"],[70,71,"pl-s"],[71,158,"pl-corl"],[158,159,"pl-s"]],[],[[37,38,"pl-s"],[38,49,"pl-c1"],[49,50,"pl-s"]],[],[[48,49,"pl-s"],[49,60,"pl-c1"],[60,61,"pl-s"]],[],[[0,17,"pl-mh"],[6,17,"pl-en"]],[[11,12,"pl-s"],[12,31,"pl-c1"],[31,32,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,23,"pl-c"],[0,1,"pl-c"]],[[7,8,"pl-k"],[9,15,"pl-c1"],[16,19,"pl-k"],[22,24,"pl-k"]],[[2,3,"pl-c1"],[10,12,"pl-k"],[14,15,"pl-smi"]],[[4,8,"pl-c1"],[9,16,"pl-s"],[9,10,"pl-pds"],[15,16,"pl-pds"],[17,18,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,9,"pl-c"],[0,1,"pl-c"]],[[0,4,"pl-c1"],[5,33,"pl-s"],[5,6,"pl-pds"],[32,33,"pl-pds"]],[],[[0,72,"pl-c"],[0,1,"pl-c"]],[[0,31,"pl-c"],[0,1,"pl-c"]],[[0,3,"pl-s"]],[[34,35,"pl-s"],[35,46,"pl-c1"],[46,47,"pl-s"]],[[0,3,"pl-s"],[3,6,"pl-en"],[6,6,"pl-c1"]],[[0,26,"pl-c1"]],[[0,22,"pl-c1"]],[[0,6,"pl-c1"]],[[0,6,"pl-c1"]],[[0,6,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[[16,17,"pl-s"],[17,28,"pl-c1"],[28,29,"pl-s"]],[[0,3,"pl-s"],[3,6,"pl-en"],[6,6,"pl-c1"]],[[0,26,"pl-c1"]],[[0,6,"pl-c1"]],[[0,6,"pl-c1"]],[[0,6,"pl-c1"]],[[0,22,"pl-c1"]],[[0,4,"pl-c1"]],[[0,11,"pl-c1"]],[[0,0,"pl-c1"]],[[0,17,"pl-c1"]],[[0,35,"pl-c1"]],[[0,7,"pl-c1"]],[[0,24,"pl-c1"]],[[0,7,"pl-c1"]],[[0,15,"pl-c1"]],[[0,22,"pl-c1"]],[[0,11,"pl-c1"]],[[0,23,"pl-c1"]],[[0,6,"pl-c1"]],[[0,15,"pl-c1"]],[[0,22,"pl-c1"]],[[0,11,"pl-c1"]],[[0,23,"pl-c1"]],[[0,6,"pl-c1"]],[[0,15,"pl-c1"]],[[0,22,"pl-c1"]],[[0,11,"pl-c1"]],[[0,23,"pl-c1"]],[[0,5,"pl-c1"]],[[0,1,"pl-c1"]],[[0,0,"pl-c1"]],[[0,85,"pl-c1"]],[[0,0,"pl-c1"]],[[0,7,"pl-c1"]],[[0,0,"pl-c1"]],[[0,44,"pl-c1"]],[[0,0,"pl-c1"]],[[0,82,"pl-c1"]],[[0,0,"pl-c1"]],[[0,42,"pl-c1"]],[[0,0,"pl-c1"]],[[0,44,"pl-c1"]],[[0,0,"pl-c1"]],[[0,7,"pl-c1"]],[[0,23,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,27,"pl-mh"],[5,27,"pl-en"],[10,11,"pl-s"],[11,18,"pl-c1"],[18,19,"pl-s"]],[[30,31,"pl-s"],[31,64,"pl-c1"],[64,65,"pl-s"],[82,83,"pl-s"],[83,96,"pl-c1"],[96,97,"pl-s"],[101,102,"pl-s"],[102,120,"pl-c1"],[120,121,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,85,"pl-c"],[2,3,"pl-c"]],[[2,18,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,16,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[],[[6,80,"pl-c"],[6,7,"pl-c"]],[[20,48,"pl-c"],[20,21,"pl-c"]],[],[],[],[[6,13,"pl-smi"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[4,7,"pl-k"]],[],[[4,77,"pl-c"],[4,5,"pl-c"]],[[4,410,"pl-c"],[4,5,"pl-c"]],[[4,49,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,21,"pl-en"]],[[6,11,"pl-k"]],[[8,116,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,29,"pl-s"],[20,21,"pl-pds"],[28,29,"pl-pds"],[30,32,"pl-k"]],[[24,52,"pl-c"],[24,25,"pl-c"]],[],[[10,15,"pl-k"],[16,31,"pl-c1"],[33,42,"pl-s"],[33,34,"pl-pds"],[41,42,"pl-pds"]],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[12,88,"pl-s"],[12,13,"pl-pds"],[87,88,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,11,"pl-k"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,29,"pl-s"],[20,21,"pl-pds"],[28,29,"pl-pds"],[30,32,"pl-k"]],[],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[12,76,"pl-s"],[12,13,"pl-pds"],[75,76,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,11,"pl-k"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,29,"pl-s"],[20,21,"pl-pds"],[28,29,"pl-pds"],[30,32,"pl-k"]],[],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[12,76,"pl-s"],[12,13,"pl-pds"],[75,76,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,11,"pl-k"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,28,"pl-s"],[20,21,"pl-pds"],[27,28,"pl-pds"],[29,31,"pl-k"]],[[10,12,"pl-k"],[13,17,"pl-c1"]],[[12,19,"pl-smi"],[20,21,"pl-k"],[22,27,"pl-c1"]],[],[[12,16,"pl-c1"]],[[10,13,"pl-k"]],[],[],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[12,87,"pl-s"],[12,13,"pl-pds"],[86,87,"pl-pds"]],[[6,9,"pl-k"]],[],[[6,11,"pl-k"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,28,"pl-s"],[20,21,"pl-pds"],[27,28,"pl-pds"],[29,31,"pl-k"]],[[10,12,"pl-k"],[13,20,"pl-smi"]],[[12,19,"pl-smi"]],[[10,14,"pl-k"]],[],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[12,82,"pl-s"],[12,13,"pl-pds"],[81,82,"pl-pds"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,21,"pl-en"]],[[6,60,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[27,55,"pl-c"],[27,28,"pl-c"]],[[10,46,"pl-s"],[10,11,"pl-pds"],[30,32,"pl-pse"],[32,40,"pl-s1"],[32,36,"pl-c1"],[40,41,"pl-pse"],[45,46,"pl-pds"]],[[10,22,"pl-s"],[10,11,"pl-pds"],[21,22,"pl-pds"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"],[17,23,"pl-e"],[17,23,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[14,15,"pl-k"],[23,24,"pl-k"],[38,66,"pl-c"],[38,39,"pl-c"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[13,14,"pl-k"]],[],[[6,57,"pl-c"],[6,7,"pl-c"]],[[6,91,"pl-c"],[6,7,"pl-c"]],[],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[10,65,"pl-s"],[10,11,"pl-pds"],[64,65,"pl-pds"]],[[6,14,"pl-smi"],[20,24,"pl-c1"],[26,28,"pl-k"],[29,37,"pl-smi"]],[[6,41,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[19,23,"pl-c1"],[25,52,"pl-c"],[25,26,"pl-c"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[],[[0,38,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,14,"pl-en"]],[[4,7,"pl-k"],[8,18,"pl-en"],[19,22,"pl-smi"],[24,30,"pl-smi"],[30,31,"pl-k"],[31,37,"pl-c1"],[45,52,"pl-smi"],[52,53,"pl-k"]],[[6,44,"pl-c"],[6,7,"pl-c"]],[[6,12,"pl-smi"],[14,21,"pl-smi"],[22,23,"pl-k"],[24,28,"pl-c1"],[30,34,"pl-c1"],[40,68,"pl-c"],[40,41,"pl-c"]],[],[[6,13,"pl-smi"],[14,15,"pl-k"],[16,21,"pl-c1"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,11,"pl-en"],[12,22,"pl-smi"],[22,23,"pl-k"],[23,27,"pl-c1"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,18,"pl-smi"],[19,20,"pl-k"],[21,31,"pl-c1"],[32,35,"pl-k"],[36,48,"pl-smi"]],[[36,48,"pl-smi"]],[[36,44,"pl-c1"],[46,48,"pl-k"],[50,56,"pl-smi"],[58,64,"pl-smi"]],[],[[8,12,"pl-c"],[8,9,"pl-c"]],[[8,30,"pl-c"],[8,9,"pl-c"]],[],[[8,12,"pl-c"],[8,9,"pl-c"]],[[6,9,"pl-k"]],[],[[6,61,"pl-c"],[6,7,"pl-c"]],[[6,81,"pl-c"],[6,7,"pl-c"]],[[6,47,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,40,"pl-s"],[11,12,"pl-pds"],[12,14,"pl-pse"],[14,38,"pl-s1"],[14,20,"pl-c1"],[38,39,"pl-pse"],[39,40,"pl-pds"]],[],[[6,66,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[14,15,"pl-k"],[16,22,"pl-c1"],[23,26,"pl-k"]],[[8,58,"pl-c"],[8,9,"pl-c"]],[[8,63,"pl-c"],[8,9,"pl-c"]],[[8,101,"pl-c"],[8,9,"pl-c"]],[[8,28,"pl-c"],[8,9,"pl-c"]],[[8,17,"pl-c"],[8,9,"pl-c"]],[[8,19,"pl-c"],[8,9,"pl-c"]],[[8,18,"pl-c"],[8,9,"pl-c"]],[[8,71,"pl-c"],[8,9,"pl-c"]],[[8,80,"pl-c"],[8,9,"pl-c"]],[[8,15,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-c1"],[13,42,"pl-s"],[13,14,"pl-pds"],[14,16,"pl-pse"],[16,40,"pl-s1"],[16,22,"pl-c1"],[40,41,"pl-pse"],[41,42,"pl-pds"],[43,69,"pl-c"],[43,44,"pl-c"]],[],[],[],[[6,12,"pl-k"],[13,20,"pl-smi"]],[[4,7,"pl-k"]],[],[[4,76,"pl-c"],[4,5,"pl-c"]],[[4,51,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,12,"pl-en"],[13,17,"pl-smi"],[17,18,"pl-k"],[18,23,"pl-c1"]],[[6,45,"pl-c"],[6,7,"pl-c"]],[[6,90,"pl-c"],[6,7,"pl-c"]],[[6,77,"pl-c"],[6,7,"pl-c"]],[[20,32,"pl-c1"],[34,62,"pl-c"],[34,35,"pl-c"]],[],[[6,61,"pl-c"],[6,7,"pl-c"]],[[6,80,"pl-c"],[6,7,"pl-c"]],[[6,55,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,40,"pl-s"],[11,12,"pl-pds"],[12,14,"pl-pse"],[14,38,"pl-s1"],[14,20,"pl-c1"],[38,39,"pl-pse"],[39,40,"pl-pds"]],[],[[6,84,"pl-c"],[6,7,"pl-c"]],[[6,49,"pl-c"],[6,7,"pl-c"]],[[6,62,"pl-c"],[6,7,"pl-c"]],[[6,58,"pl-c"],[6,7,"pl-c"]],[[6,13,"pl-smi"],[19,21,"pl-k"],[22,29,"pl-smi"],[30,32,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,21,"pl-en"],[22,29,"pl-smi"]],[[6,13,"pl-smi"],[14,16,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,22,"pl-en"]],[[6,11,"pl-k"]],[[14,15,"pl-k"],[16,22,"pl-smi"]],[[8,76,"pl-c"],[8,9,"pl-c"]],[[16,17,"pl-k"],[26,27,"pl-k"],[28,35,"pl-smi"]],[[13,14,"pl-k"],[15,27,"pl-smi"]],[[8,12,"pl-c"],[8,9,"pl-c"]],[],[[8,13,"pl-k"],[14,21,"pl-smi"],[22,24,"pl-k"],[25,29,"pl-c1"]],[[10,109,"pl-c"],[10,11,"pl-c"]],[[10,45,"pl-c"],[10,11,"pl-c"]],[[10,38,"pl-c"],[10,11,"pl-c"]],[[10,32,"pl-c"],[10,11,"pl-c"]],[[10,15,"pl-c"],[10,11,"pl-c"]],[[10,78,"pl-c"],[10,11,"pl-c"]],[[14,15,"pl-k"],[16,18,"pl-c1"],[19,25,"pl-c1"]],[],[[25,27,"pl-k"],[29,33,"pl-smi"]],[[12,14,"pl-k"],[20,22,"pl-k"]],[[14,83,"pl-c"],[14,15,"pl-c"]],[[14,19,"pl-k"],[20,22,"pl-k"],[36,64,"pl-c"],[36,37,"pl-c"]],[[12,16,"pl-k"]],[[14,16,"pl-k"],[20,21,"pl-k"]],[[23,24,"pl-k"],[25,31,"pl-c1"],[32,35,"pl-k"],[40,47,"pl-smi"]],[],[[16,21,"pl-c"],[16,17,"pl-c"]],[[21,23,"pl-k"]],[],[[14,17,"pl-k"]],[[12,15,"pl-k"]],[[10,13,"pl-k"]],[[8,11,"pl-k"]],[],[[8,46,"pl-c"],[8,9,"pl-c"]],[[26,28,"pl-k"],[29,36,"pl-smi"],[37,39,"pl-k"],[40,45,"pl-c1"],[46,48,"pl-k"],[49,56,"pl-smi"],[57,59,"pl-k"],[60,68,"pl-c1"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,12,"pl-k"]],[[8,65,"pl-c"],[8,9,"pl-c"]],[[8,63,"pl-c"],[8,9,"pl-c"]],[[8,103,"pl-c"],[8,9,"pl-c"]],[[8,33,"pl-c"],[8,9,"pl-c"]],[[8,56,"pl-c"],[8,9,"pl-c"]],[[8,73,"pl-c"],[8,9,"pl-c"]],[[8,26,"pl-c"],[8,9,"pl-c"]],[[8,13,"pl-c"],[8,9,"pl-c"]],[[8,12,"pl-c1"],[13,42,"pl-s"],[13,14,"pl-pds"],[14,16,"pl-pse"],[16,40,"pl-s1"],[16,22,"pl-c1"],[40,41,"pl-pse"],[41,42,"pl-pds"]],[],[[8,14,"pl-smi"]],[[8,15,"pl-smi"]],[],[[8,13,"pl-c"],[8,9,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[10,11,"pl-k"],[12,18,"pl-smi"],[24,25,"pl-c1"]],[],[[6,10,"pl-k"]],[[6,10,"pl-k"],[11,23,"pl-c1"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,23,"pl-c1"],[24,76,"pl-c"],[24,25,"pl-c"]],[[8,14,"pl-k"],[15,19,"pl-c1"]],[[6,10,"pl-k"],[11,23,"pl-c1"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,23,"pl-c1"]],[[8,14,"pl-k"],[15,19,"pl-c1"]],[[6,10,"pl-k"],[11,26,"pl-c1"]],[[8,15,"pl-smi"],[16,17,"pl-k"],[18,26,"pl-c1"]],[[8,14,"pl-k"],[15,19,"pl-c1"]],[[6,9,"pl-k"]],[],[[6,12,"pl-k"],[13,18,"pl-c1"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,25,"pl-en"]],[[6,8,"pl-k"],[9,21,"pl-smi"]],[[8,20,"pl-smi"],[30,58,"pl-c"],[30,31,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,7,"pl-k"],[8,18,"pl-en"]],[[4,71,"pl-c"],[4,5,"pl-c"]],[[4,7,"pl-k"],[8,16,"pl-en"],[17,24,"pl-smi"],[24,25,"pl-k"],[25,26,"pl-k"],[26,27,"pl-c1"]],[[14,15,"pl-k"],[16,22,"pl-smi"],[35,37,"pl-k"]],[[8,17,"pl-smi"],[18,19,"pl-k"],[20,24,"pl-c1"]],[[8,70,"pl-c"],[8,9,"pl-c"]],[[8,18,"pl-smi"]],[[8,17,"pl-smi"]],[],[[8,13,"pl-c"],[8,9,"pl-c"]],[],[[8,53,"pl-c"],[8,9,"pl-c"]],[[8,34,"pl-c"],[8,9,"pl-c"]],[[8,50,"pl-c"],[8,9,"pl-c"]],[[8,104,"pl-c"],[8,9,"pl-c"]],[[8,35,"pl-c"],[8,9,"pl-c"]],[[8,16,"pl-smi"]],[[6,9,"pl-k"]],[],[[6,58,"pl-c"],[6,7,"pl-c"]],[[19,21,"pl-k"],[23,29,"pl-smi"]],[],[[6,9,"pl-k"]],[],[[6,14,"pl-smi"],[15,16,"pl-k"],[17,18,"pl-c1"]],[[6,14,"pl-smi"],[15,16,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,18,"pl-en"],[19,22,"pl-smi"],[24,27,"pl-smi"],[29,30,"pl-k"],[30,35,"pl-smi"],[37,38,"pl-k"],[38,43,"pl-smi"]],[[6,9,"pl-c"],[6,7,"pl-c"]],[[6,12,"pl-smi"],[13,14,"pl-k"],[15,20,"pl-c1"],[21,24,"pl-k"]],[[6,14,"pl-smi"],[15,16,"pl-k"],[17,18,"pl-c1"],[19,51,"pl-c"],[19,20,"pl-c"]],[[6,11,"pl-smi"],[12,13,"pl-k"],[17,104,"pl-c"],[17,18,"pl-c"]],[[6,10,"pl-smi"],[11,12,"pl-k"],[13,20,"pl-c1"],[26,46,"pl-c"],[26,27,"pl-c"]],[[6,12,"pl-smi"],[13,14,"pl-k"],[21,94,"pl-c"],[21,22,"pl-c"]],[[6,14,"pl-smi"],[15,16,"pl-k"]],[],[[6,12,"pl-smi"],[25,27,"pl-k"]],[[8,12,"pl-smi"],[36,69,"pl-c"],[36,37,"pl-c"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,20,"pl-en"]],[[6,14,"pl-smi"],[15,17,"pl-k"],[18,19,"pl-c1"]],[],[[6,29,"pl-c"],[6,7,"pl-c"]],[[6,85,"pl-c"],[6,7,"pl-c"]],[[9,10,"pl-k"],[11,17,"pl-c1"],[18,21,"pl-k"],[22,30,"pl-smi"],[32,34,"pl-k"],[36,43,"pl-smi"]],[[14,15,"pl-k"],[16,22,"pl-smi"]],[[14,15,"pl-k"],[16,22,"pl-smi"]],[[8,12,"pl-c"],[8,9,"pl-c"]],[],[[8,13,"pl-k"],[14,18,"pl-c1"]],[[15,16,"pl-k"],[17,20,"pl-c1"]],[],[[19,20,"pl-k"],[21,25,"pl-c1"]],[],[[28,30,"pl-k"]],[[12,17,"pl-k"]],[[14,19,"pl-c"],[14,15,"pl-c"]],[],[[14,16,"pl-k"],[17,26,"pl-smi"]],[[25,26,"pl-k"],[27,32,"pl-c1"]],[[16,21,"pl-k"]],[[14,17,"pl-k"]],[],[[14,19,"pl-c"],[14,15,"pl-c"]],[[14,97,"pl-c"],[14,15,"pl-c"]],[[14,65,"pl-c"],[14,15,"pl-c"]],[],[],[[14,22,"pl-smi"],[23,25,"pl-k"],[26,27,"pl-c1"]],[[12,15,"pl-k"]],[],[[12,17,"pl-c"],[12,13,"pl-c"]],[[10,13,"pl-k"]],[],[[10,15,"pl-k"],[16,22,"pl-k"]],[],[[10,15,"pl-c"],[10,11,"pl-c"]],[[8,11,"pl-k"]],[],[[26,28,"pl-k"]],[[10,18,"pl-smi"],[19,21,"pl-k"],[22,23,"pl-c1"]],[[10,18,"pl-smi"]],[[8,11,"pl-k"]],[[6,9,"pl-k"],[10,34,"pl-c"],[10,11,"pl-c"]],[],[[6,14,"pl-smi"],[15,17,"pl-k"]],[],[],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[],[],[[37,38,"pl-s"],[38,59,"pl-c1"],[59,60,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,40,"pl-c"],[0,1,"pl-c"]],[[0,6,"pl-k"],[7,11,"pl-en"]],[[2,85,"pl-c"],[2,3,"pl-c"]],[[2,18,"pl-c"],[2,3,"pl-c"]],[[2,7,"pl-k"],[8,16,"pl-en"]],[[4,7,"pl-k"],[8,11,"pl-en"]],[[6,10,"pl-c"],[6,7,"pl-c"]],[],[[6,80,"pl-c"],[6,7,"pl-c"]],[[20,48,"pl-c"],[20,21,"pl-c"]],[],[],[],[[6,27,"pl-c"],[6,7,"pl-c"]],[[6,10,"pl-c1"],[11,40,"pl-s"],[11,12,"pl-pds"],[25,27,"pl-pse"],[27,38,"pl-s1"],[27,34,"pl-c1"],[38,39,"pl-pse"],[39,40,"pl-pds"]],[],[[6,13,"pl-smi"]],[],[[6,11,"pl-c"],[6,7,"pl-c"]],[[4,7,"pl-k"]],[],[[4,7,"pl-k"],[8,21,"pl-en"]],[[6,11,"pl-c"],[6,7,"pl-c"]],[[6,11,"pl-k"]],[[8,116,"pl-c"],[8,9,"pl-c"]],[[8,14,"pl-c1"],[15,19,"pl-c1"],[20,29,"pl-s"],[20,21,"pl-pds"],[28,29,"pl-pds"],[30,32,"pl-k"]],[[10,55,"pl-c"],[10,11,"pl-c"]],[[10,21,"pl-c"],[10,11,"pl-c"]],[[10,70,"pl-c"],[10,11,"pl-c"]],[[10,68,"pl-c"],[10,11,"pl-c"]],[[10,70,"pl-c"],[10,11,"pl-c"]],[[10,73,"pl-c"],[10,11,"pl-c"]],[[10,69,"pl-c"],[10,11,"pl-c"]],[[10,98,"pl-c"],[10,11,"pl-c"]],[[10,110,"pl-c"],[10,11,"pl-c"]],[[10,97,"pl-c"],[10,11,"pl-c"]],[[10,101,"pl-c"],[10,11,"pl-c"]],[[10,69,"pl-c"],[10,11,"pl-c"]],[[10,84,"pl-c"],[10,11,"pl-c"]],[[10,67,"pl-c"],[10,11,"pl-c"]],[[10,82,"pl-c"],[10,11,"pl-c"]],[[10,76,"pl-c"],[10,11,"pl-c"]],[[10,87,"pl-c"],[10,11,"pl-c"]],[[10,66,"pl-c"],[10,11,"pl-c"]],[[10,63,"pl-c"],[10,11,"pl-c"]],[[10,13,"pl-c"],[10,11,"pl-c"]],[[10,14,"pl-c1"],[15,42,"pl-s"],[15,16,"pl-pds"],[24,26,"pl-pse"],[26,40,"pl-s1"],[26,32,"pl-c1"],[40,41,"pl-pse"],[41,42,"pl-pds"]],[],[[10,96,"pl-c"],[10,11,"pl-c"]],[[10,14,"pl-c1"],[15,44,"pl-s"],[15,16,"pl-pds"],[29,31,"pl-pse"],[31,42,"pl-s1"],[31,38,"pl-c1"],[42,43,"pl-pse"],[43,44,"pl-pds"]],[],[],[],[[10,68,"pl-c"],[10,11,"pl-c"]],[[10,75,"pl-c"],[10,11,"pl-c"]],[[10,95,"pl-c"],[10,11,"pl-c"]],[[10,96,"pl-c"],[10,11,"pl-c"]],[[10,61,"pl-c"],[10,11,"pl-c"]],[[10,71,"pl-c"],[10,11,"pl-c"]],[[10,15,"pl-k"],[16,31,"pl-c1"],[33,42,"pl-s"],[33,34,"pl-pds"],[41,42,"pl-pds"]],[[8,11,"pl-k"]],[[6,12,"pl-k"],[13,22,"pl-c1"]],[[8,104,"pl-c"],[8,9,"pl-c"]],[[12,88,"pl-s"],[12,13,"pl-pds"],[87,88,"pl-pds"]],[[6,9,"pl-k"]],[[4,7,"pl-k"]],[[2,5,"pl-k"]],[[0,3,"pl-k"]],[[0,3,"pl-s"]],[],[],[]],"colorizedLines":null}},"title":"leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java","appPayload":{},"meta":{"title":"leetcode-python-java/README.md at master · leetcode-python-java/leetcode-python-java"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/leetcode-python-java/leetcode-python-java" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/leetcode-python-java/leetcode-python-java/tree/master" data-discover="true">leetcode-python-java</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_5ipla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_5ipla9lik5_ _R_5ipla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_5ipla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_v4pla9lik5_" id="_R_14pla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_v4pla9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_v4tla9lik5_" id="_R_14tla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_v4tla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/leetcode-python-java/leetcode-python-java/commits/master/README.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/leetcode-python-java/leetcode-python-java/commits/master/README.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="88.3 KB" style="--truncate-max-width:100%"><span>2776 lines (2355 loc) · 88.3 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/leetcode-python-java/leetcode-python-java/tree/master" data-discover="true">leetcode-python-java</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="88.3 KB" style="--truncate-max-width:100%"><span>2776 lines (2355 loc) · 88.3 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/leetcode-python-java/leetcode-python-java/raw/refs/heads/master/README.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Learn-Rails-by-Reading-Source-Code</h1><a id="user-content-learn-rails-by-reading-source-code" class="anchor" aria-label="Permalink: Learn-Rails-by-Reading-Source-Code" href="#learn-rails-by-reading-source-code"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="https://github.com/996icu/996.ICU/blob/master/LICENSE"><img src="https://camo.githubusercontent.com/be80b8cb211ceb2263744e99fdb161a40124901906fd7c7f47d6361760dd7e8b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d416e74692532303939362d626c75652e737667" alt="LICENSE" data-canonical-src="https://img.shields.io/badge/license-Anti%20996-blue.svg" style="max-width: 100%;"></a>
<a href="https://996.icu" rel="nofollow"><img src="https://camo.githubusercontent.com/ac8f294a80f65338db545230f1a881b9a382204a1f187c6ff40ee679d42d40ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c696e6b2d3939362e6963752d7265642e737667" alt="996.icu" data-canonical-src="https://img.shields.io/badge/link-996.icu-red.svg" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Table of Contents</h2><a id="user-content-table-of-contents" class="anchor" aria-label="Permalink: Table of Contents" href="#table-of-contents"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="#part-0-before-reading-rails-5-source-code">Part 0: Before reading Rails 5 source code</a>
<ul dir="auto">
<li><a href="#what-will-you-learn-from-this-tutorial">What will you learn from this tutorial?</a></li>
</ul>
</li>
<li><a href="#part-1-your-app-an-instance-of-yourprojectapplication">Part 1: Your app: an instance of YourProject::Application</a></li>
<li><a href="#part-2-config">Part 2: config</a></li>
<li><a href="#part-3-every-request-and-response">Part 3: Every request and response</a>
<ul dir="auto">
<li><a href="#puma">Puma</a></li>
<li><a href="#rack-apps">Rack apps</a></li>
<li><a href="#the-core-app-actiondispatchroutingrouteset-instance">The core app: ActionDispatch::Routing::RouteSet instance</a></li>
<li><a href="#render-view">Render view</a></li>
<li><a href="#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file">How can instance variables defined in Controller be accessed in view file?</a></li>
</ul>
</li>
<li><a href="#part-4-what-does--rails-server-do">Part 4: What does <code>$ rails server</code> do?</a>
<ul dir="auto">
<li><a href="#thor">Thor</a></li>
<li><a href="#railsserverstart">Rails::Server#start</a></li>
<li><a href="#starting-puma">Starting Puma</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#exiting-puma">Exiting Puma</a>
<ul dir="auto">
<li><a href="#process-and-thread">Process and Thread</a></li>
<li><a href="#send-sigterm-to-puma">Send <code>SIGTERM</code> to Puma</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Part 0: Before reading Rails 5 source code</h2><a id="user-content-part-0-before-reading-rails-5-source-code" class="anchor" aria-label="Permalink: Part 0: Before reading Rails 5 source code" href="#part-0-before-reading-rails-5-source-code"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>I suggest you to learn Rack <a href="http://rack.github.io/" rel="nofollow">http://rack.github.io/</a> first.</li>
</ol>
<p dir="auto">In Rack, an object with <code>call</code> method is a Rack app.</p>
<p dir="auto">So what is the object with <code>call</code> method in Rails? I will answer this question in Part 1.</p>
<ol start="2" dir="auto">
<li>You need a good IDE which can help for debugging. I use <a href="https://www.jetbrains.com/" rel="nofollow">RubyMine</a>.</li>
</ol>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">What will you learn from this tutorial?</h3><a id="user-content-what-will-you-learn-from-this-tutorial" class="anchor" aria-label="Permalink: What will you learn from this tutorial?" href="#what-will-you-learn-from-this-tutorial"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>
<p dir="auto">How does Rails start your application?</p>
</li>
<li>
<p dir="auto">How does Rails process every request?</p>
</li>
<li>
<p dir="auto">How does Rails combine ActionController, ActionView and Routes together?</p>
</li>
<li>
<p dir="auto">How does Puma, Rack, Rails work together?</p>
</li>
<li>
<p dir="auto">What's Puma's multiple threads?</p>
</li>
</ul>
<p dir="auto">I should start with the command <code>$ rails server</code>, but I put this to Part 4. Because it's a little bit complex.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Part 1: Your app: an instance of YourProject::Application</h2><a id="user-content-part-1-your-app-an-instance-of-yourprojectapplication" class="anchor" aria-label="Permalink: Part 1: Your app: an instance of YourProject::Application" href="#part-1-your-app-an-instance-of-yourprojectapplication"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Assume your Rails app's class name is <code>YourProject::Application</code> (defined in <code>./config/application.rb</code>).</p>
<p dir="auto">First, I will give you a piece of important code.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb
module Rails
  module Command
    class ServerCommand &lt; Base
      def perform
        # ...
        Rails::Server.new(server_options).tap do |server|
          # APP_PATH is '/path/to/your_project/config/application'.
          # require APP_PATH will create the 'Rails.application' object.
          # Actually, 'Rails.application' is an instance of `YourProject::Application`.
          # Rack server will start 'Rails.application'.
          require APP_PATH
          
          Dir.chdir(Rails.application.root)
          
          server.start
        end
      end
    end
  end
  
  class Server &lt; ::Rack::Server
    def start
      #...
      # 'wrapped_app' will get an well prepared app from `./config.ru` file.
      # 'wrapped_app' will return an instance of `YourProject::Application`.
      # But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.
      # It has been created when `require APP_PATH` in previous code: 
      # in Rails::Command::ServerCommand#perform
      wrapped_app   

      super # Will invoke ::Rack::Server#start. 
    end
  end
end"><pre><span class="pl-c"># ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-k">class</span> <span class="pl-v">ServerCommand</span> &lt; <span class="pl-v">Base</span>
      <span class="pl-k">def</span> <span class="pl-en">perform</span>
        <span class="pl-c"># ...</span>
        <span class="pl-v">Rails</span>::<span class="pl-v">Server</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-en">server_options</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">tap</span> <span class="pl-k">do</span> |<span class="pl-s1">server</span>|
          <span class="pl-c"># APP_PATH is '/path/to/your_project/config/application'.</span>
          <span class="pl-c"># require APP_PATH will create the 'Rails.application' object.</span>
          <span class="pl-c"># Actually, 'Rails.application' is an instance of `YourProject::Application`.</span>
          <span class="pl-c"># Rack server will start 'Rails.application'.</span>
          <span class="pl-en">require</span> <span class="pl-c1">APP_PATH</span>
          
          <span class="pl-v">Dir</span><span class="pl-kos">.</span><span class="pl-en">chdir</span><span class="pl-kos">(</span><span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span><span class="pl-kos">.</span><span class="pl-en">root</span><span class="pl-kos">)</span>
          
          <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">start</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
  
  <span class="pl-k">class</span> <span class="pl-v">Server</span> &lt; ::<span class="pl-v">Rack</span>::<span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">start</span>
      <span class="pl-c">#...</span>
      <span class="pl-c"># 'wrapped_app' will get an well prepared app from `./config.ru` file.</span>
      <span class="pl-c"># 'wrapped_app' will return an instance of `YourProject::Application`.</span>
      <span class="pl-c"># But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.</span>
      <span class="pl-c"># It has been created when `require APP_PATH` in previous code: </span>
      <span class="pl-c"># in Rails::Command::ServerCommand#perform</span>
      <span class="pl-en">wrapped_app</span>   

      <span class="pl-smi">super</span> <span class="pl-c"># Will invoke ::Rack::Server#start. </span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">A Rack server need to start with an <code>App</code> object. The <code>App</code> object should have a <code>call</code> method.</p>
<p dir="auto"><code>config.ru</code> is the conventional entry file for Rack app. So let's look at it.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config.ru
require_relative 'config/environment'

run Rails.application # It seems that this is the app."><pre><span class="pl-c"># ./config.ru</span>
<span class="pl-en">require_relative</span> <span class="pl-s">'config/environment'</span>

<span class="pl-en">run</span> <span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span> <span class="pl-c"># It seems that this is the app.</span></pre></div>
<p dir="auto">Let's test it by <code>Rails.application.respond_to?(:call)</code>, it returns <code>true</code>.</p>
<p dir="auto">Let's step into <code>Rails.application</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties-5.2.2/lib/rails.rb
module Rails
  class &lt;&lt; self
    @application = @app_class = nil

    attr_accessor :app_class
    
    # Oh, 'application' is a class method for module 'Rails'. It is not an object.
    # But it returns an object which is an instance of 'app_class'.
    # So it is important for us to know what class 'app_class' is.
    def application
      @application ||= (app_class.instance if app_class)  
    end
  end
end"><pre><span class="pl-c"># ./gems/railties-5.2.2/lib/rails.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
    <span class="pl-c1">@application</span> <span class="pl-c1">=</span> <span class="pl-c1">@app_class</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>

    <span class="pl-en">attr_accessor</span> <span class="pl-pds">:app_class</span>
    
    <span class="pl-c"># Oh, 'application' is a class method for module 'Rails'. It is not an object.</span>
    <span class="pl-c"># But it returns an object which is an instance of 'app_class'.</span>
    <span class="pl-c"># So it is important for us to know what class 'app_class' is.</span>
    <span class="pl-k">def</span> <span class="pl-en">application</span>
      <span class="pl-c1">@application</span> ||= <span class="pl-kos">(</span><span class="pl-en">app_class</span><span class="pl-kos">.</span><span class="pl-en">instance</span> <span class="pl-k">if</span> <span class="pl-en">app_class</span><span class="pl-kos">)</span>  
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">Because <code>Rails.application.respond_to?(:call)</code> returns <code>true</code>, <code>app_class.instance</code> has a <code>call</code> method.</p>
<p dir="auto">When was <code>app_class</code> set?</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Rails
  class Application &lt; Engine
    class &lt;&lt; self
      def inherited(base) # This is a hooked method.
        Rails.app_class = base # This line set the 'app_class'.
      end
    end
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Engine</span>
    <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
      <span class="pl-k">def</span> <span class="pl-en">inherited</span><span class="pl-kos">(</span><span class="pl-s1">base</span><span class="pl-kos">)</span> <span class="pl-c"># This is a hooked method.</span>
        <span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">app_class</span> <span class="pl-c1">=</span> <span class="pl-s1">base</span> <span class="pl-c"># This line set the 'app_class'.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto"><code>Rails::Application</code> is inherited by <code>YourProject</code>,</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config/application.rb
module YourProject
  # The hooked method `inherited` will be invoked here.
  class Application &lt; Rails::Application
  end
end"><pre><span class="pl-c"># ./config/application.rb</span>
<span class="pl-k">module</span> <span class="pl-v">YourProject</span>
  <span class="pl-c"># The hooked method `inherited` will be invoked here.</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Rails</span>::<span class="pl-v">Application</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">So <code>YourProject::Application</code> is the <code>Rails.app_class</code> here.</p>
<p dir="auto">You may have a question: When does Rails execute the code in <code>./config/application.rb</code>?</p>
<p dir="auto">To answer this question, we need to look back to <code>config.ru</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config.ru
require_relative 'config/environment' # Let's step into this line.

run Rails.application # It seems that this is the app."><pre><span class="pl-c"># ./config.ru</span>
<span class="pl-en">require_relative</span> <span class="pl-s">'config/environment'</span> <span class="pl-c"># Let's step into this line.</span>

<span class="pl-en">run</span> <span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span> <span class="pl-c"># It seems that this is the app.</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config/environment.rb
# Load the Rails application.
require_relative 'application' # Let's step into this line.

# Initialize the Rails application.
Rails.application.initialize!"><pre><span class="pl-c"># ./config/environment.rb</span>
<span class="pl-c"># Load the Rails application.</span>
<span class="pl-en">require_relative</span> <span class="pl-s">'application'</span> <span class="pl-c"># Let's step into this line.</span>

<span class="pl-c"># Initialize the Rails application.</span>
<span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span><span class="pl-kos">.</span><span class="pl-en">initialize!</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config/application.rb
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module YourProject
  # The hooked method `inherited` will be invoked here.
  class Application &lt; Rails::Application
    config.load_defaults 5.2
    config.i18n.default_locale = :zh
  end
end"><pre><span class="pl-c"># ./config/application.rb</span>
<span class="pl-en">require_relative</span> <span class="pl-s">'boot'</span>

<span class="pl-en">require</span> <span class="pl-s">'rails/all'</span>

<span class="pl-c"># Require the gems listed in Gemfile, including any gems</span>
<span class="pl-c"># you've limited to :test, :development, or :production.</span>
<span class="pl-v">Bundler</span><span class="pl-kos">.</span><span class="pl-en">require</span><span class="pl-kos">(</span>*<span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">groups</span><span class="pl-kos">)</span>

<span class="pl-k">module</span> <span class="pl-v">YourProject</span>
  <span class="pl-c"># The hooked method `inherited` will be invoked here.</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Rails</span>::<span class="pl-v">Application</span>
    <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">load_defaults</span> <span class="pl-c1">5.2</span>
    <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">i18n</span><span class="pl-kos">.</span><span class="pl-en">default_locale</span> <span class="pl-c1">=</span> <span class="pl-pds">:zh</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">Because <code>YourProject::Application</code> is <code>Rails.app_class</code>, <code>app_class.instance</code> is <code>YourProject::Application.instance</code>.</p>
<p dir="auto">But where is the <code>call</code> method?</p>
<p dir="auto"><code>call</code> method should be a method of <code>YourProject::Application.instance</code>.</p>
<p dir="auto">The <code>call</code> method processes every request. Here it is.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties/lib/rails/engine.rb
module Rails
  class Engine &lt; Railtie
    def call(env) # This method will process every request. It is invoked by Rack. So it is very important. 
      req = build_request env
      app.call req.env # We will discuss the 'app' object later.
    end
  end
end

# ./gems/railties/lib/rails/application.rb
module Rails
  class Application &lt; Engine
  end
end

# ./config/application.rb
module YourProject
  class Application &lt; Rails::Application
  end
end"><pre><span class="pl-c"># ./gems/railties/lib/rails/engine.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Engine</span> &lt; <span class="pl-v">Railtie</span>
    <span class="pl-k">def</span> <span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span> <span class="pl-c"># This method will process every request. It is invoked by Rack. So it is very important. </span>
      <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-en">build_request</span> <span class="pl-s1">env</span>
      <span class="pl-en">app</span><span class="pl-kos">.</span><span class="pl-en">call</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">env</span> <span class="pl-c"># We will discuss the 'app' object later.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/railties/lib/rails/application.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Engine</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./config/application.rb</span>
<span class="pl-k">module</span> <span class="pl-v">YourProject</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Rails</span>::<span class="pl-v">Application</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">Ancestor's chain is <code>YourProject::Application &lt; Rails::Application &lt; Rails::Engine &lt; Rails::Railtie</code>.</p>
<p dir="auto">So <code>YourProject::Application.new.respond_to?(:call)</code> returns <code>true</code>.</p>
<p dir="auto">But what does <code>app_class.instance</code> really do?</p>
<p dir="auto"><code>instance</code> is just a method name. What we really expects is something like <code>app_class.new</code>.</p>
<p dir="auto">Let's look at the definition of <code>instance</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties/lib/rails/application.rb
module Rails
  class Application &lt; Engine
    def instance
      super.run_load_hooks! # This line confused me at the beginning. 
    end
  end
end"><pre><span class="pl-c"># ./gems/railties/lib/rails/application.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Engine</span>
    <span class="pl-k">def</span> <span class="pl-en">instance</span>
      <span class="pl-smi">super</span><span class="pl-kos">.</span><span class="pl-en">run_load_hooks!</span> <span class="pl-c"># This line confused me at the beginning. </span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">After a deep research, I realized that this code is equal to:</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="def instance
  return_value = super # Keyword 'super' means call the ancestor's same name method: 'instance'.
  return_value.run_load_hooks!
end"><pre><span class="pl-k">def</span> <span class="pl-en">instance</span>
  <span class="pl-s1">return_value</span> <span class="pl-c1">=</span> <span class="pl-smi">super</span> <span class="pl-c"># Keyword 'super' means call the ancestor's same name method: 'instance'.</span>
  <span class="pl-s1">return_value</span><span class="pl-kos">.</span><span class="pl-en">run_load_hooks!</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties/lib/rails/railtie.rb
module Rails
  class Railtie
    def instance
      # 'Rails::Railtie' is the top ancestor class.
      # Now 'app_class.instance' is 'YourProject::Application.new'.
      @instance ||= new
    end
  end
end"><pre><span class="pl-c"># ./gems/railties/lib/rails/railtie.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Railtie</span>
    <span class="pl-k">def</span> <span class="pl-en">instance</span>
      <span class="pl-c"># 'Rails::Railtie' is the top ancestor class.</span>
      <span class="pl-c"># Now 'app_class.instance' is 'YourProject::Application.new'.</span>
      <span class="pl-c1">@instance</span> ||= <span class="pl-en">new</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Rails
  def application
    @application ||= (app_class.instance if app_class)
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">def</span> <span class="pl-en">application</span>
    <span class="pl-c1">@application</span> ||= <span class="pl-kos">(</span><span class="pl-en">app_class</span><span class="pl-kos">.</span><span class="pl-en">instance</span> <span class="pl-k">if</span> <span class="pl-en">app_class</span><span class="pl-kos">)</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">So <code>YourProject::Application.new</code> is <code>Rails.application</code>.</p>
<p dir="auto">Rack server will start <code>Rails.application</code> in the end.</p>
<p dir="auto"><code>Rails.application</code> is an important object in Rails.</p>
<p dir="auto">And you'll only have one <code>Rails.application</code> in one Puma process.</p>
<p dir="auto">Multiple threads in a Puma process shares the <code>Rails.application</code>.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Part 2: config</h2><a id="user-content-part-2-config" class="anchor" aria-label="Permalink: Part 2: config" href="#part-2-config"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The first time we see the <code>config</code> is in <code>./config/application.rb</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config/application.rb
#...
module YourProject
  class Application &lt; Rails::Application
    # Actually, `config` is a method of `YourProject::Application`.
    # It is defined in it's grandfather's father: `Rails::Railtie`
    config.load_defaults 5.2  # Let's step into this line to see what is config.
    config.i18n.default_locale = :zh
  end
end"><pre><span class="pl-c"># ./config/application.rb</span>
<span class="pl-c">#...</span>
<span class="pl-k">module</span> <span class="pl-v">YourProject</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Rails</span>::<span class="pl-v">Application</span>
    <span class="pl-c"># Actually, `config` is a method of `YourProject::Application`.</span>
    <span class="pl-c"># It is defined in it's grandfather's father: `Rails::Railtie`</span>
    <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">load_defaults</span> <span class="pl-c1">5.2</span>  <span class="pl-c"># Let's step into this line to see what is config.</span>
    <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">i18n</span><span class="pl-kos">.</span><span class="pl-en">default_locale</span> <span class="pl-c1">=</span> <span class="pl-pds">:zh</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Rails
  class Railtie
    class &lt;&lt; self
      # Method `:config` is defined here.
      # Actually, method `:config` is delegated to another object `:instance`.
      delegate :config, to: :instance 
      
      # Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`
      def instance
        # return an instance of `YourProject::Application`.
        # Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`
        @instance ||= new 
      end
    end
  end
  
  class Engine &lt; Railtie
  end
  
  class Application &lt; Engine
    class &lt;&lt; self
      def instance
        # 'super' will call `:instance` method in `Railtie`, 
        # which will return an instance of `YourProject::Application`.
        return_value = super  
        return_value.run_load_hooks!
      end
    end
    
    def run_load_hooks!
      return self if @ran_load_hooks
      @ran_load_hooks = true

      # ...
      self # `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.
    end
    
    # This is the method `config`.
    def config
      # It is an instance of class `Rails::Application::Configuration`. 
      # Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   
      @config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))
    end
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Railtie</span>
    <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
      <span class="pl-c"># Method `:config` is defined here.</span>
      <span class="pl-c"># Actually, method `:config` is delegated to another object `:instance`.</span>
      <span class="pl-en">delegate</span> <span class="pl-pds">:config</span><span class="pl-kos">,</span> <span class="pl-pds">to</span>: <span class="pl-pds">:instance</span> 
      
      <span class="pl-c"># Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`</span>
      <span class="pl-k">def</span> <span class="pl-en">instance</span>
        <span class="pl-c"># return an instance of `YourProject::Application`.</span>
        <span class="pl-c"># Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`</span>
        <span class="pl-c1">@instance</span> ||= <span class="pl-en">new</span> 
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
  
  <span class="pl-k">class</span> <span class="pl-v">Engine</span> &lt; <span class="pl-v">Railtie</span>
  <span class="pl-k">end</span>
  
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Engine</span>
    <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
      <span class="pl-k">def</span> <span class="pl-en">instance</span>
        <span class="pl-c"># 'super' will call `:instance` method in `Railtie`, </span>
        <span class="pl-c"># which will return an instance of `YourProject::Application`.</span>
        <span class="pl-s1">return_value</span> <span class="pl-c1">=</span> <span class="pl-smi">super</span>  
        <span class="pl-s1">return_value</span><span class="pl-kos">.</span><span class="pl-en">run_load_hooks!</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">run_load_hooks!</span>
      <span class="pl-k">return</span> <span class="pl-smi">self</span> <span class="pl-k">if</span> <span class="pl-c1">@ran_load_hooks</span>
      <span class="pl-c1">@ran_load_hooks</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>

      <span class="pl-c"># ...</span>
      <span class="pl-smi">self</span> <span class="pl-c"># `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># This is the method `config`.</span>
    <span class="pl-k">def</span> <span class="pl-en">config</span>
      <span class="pl-c"># It is an instance of class `Rails::Application::Configuration`. </span>
      <span class="pl-c"># Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   </span>
      <span class="pl-c1">@config</span> ||= <span class="pl-v">Application</span>::<span class="pl-v">Configuration</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">find_root</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">called_from</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">In the end, <code>YourProject::Application.config === Rails.application.config</code> returns <code>true</code>.</p>
<p dir="auto">Invoke Class's <code>config</code> method become invoke the class's instance's <code>config</code> method.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Rails
  class &lt;&lt; self
    def configuration
      application.config
    end 
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
    <span class="pl-k">def</span> <span class="pl-en">configuration</span>
      <span class="pl-en">application</span><span class="pl-kos">.</span><span class="pl-en">config</span>
    <span class="pl-k">end</span> 
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">So <code>Rails.configuration === Rails.application.config</code> returns <code>true</code>.</p>
<p dir="auto">FYI:</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Rails
  class Application
    class Configuration &lt; ::Rails::Engine::Configuration
    end
  end
  
  class Engine
    class Configuration &lt; ::Rails::Railtie::Configuration
      attr_accessor :middleware

      def initialize(root = nil)
        super()
        #...
        @middleware = Rails::Configuration::MiddlewareStackProxy.new
      end
    end
  end
  
  class Railtie
    class Configuration
    end
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span>
    <span class="pl-k">class</span> <span class="pl-v">Configuration</span> &lt; ::<span class="pl-v">Rails</span>::<span class="pl-v">Engine</span>::<span class="pl-v">Configuration</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
  
  <span class="pl-k">class</span> <span class="pl-v">Engine</span>
    <span class="pl-k">class</span> <span class="pl-v">Configuration</span> &lt; ::<span class="pl-v">Rails</span>::<span class="pl-v">Railtie</span>::<span class="pl-v">Configuration</span>
      <span class="pl-en">attr_accessor</span> <span class="pl-pds">:middleware</span>

      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">root</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">)</span>
        <span class="pl-smi">super</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
        <span class="pl-c">#...</span>
        <span class="pl-c1">@middleware</span> <span class="pl-c1">=</span> <span class="pl-v">Rails</span>::<span class="pl-v">Configuration</span>::<span class="pl-v">MiddlewareStackProxy</span><span class="pl-kos">.</span><span class="pl-en">new</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
  
  <span class="pl-k">class</span> <span class="pl-v">Railtie</span>
    <span class="pl-k">class</span> <span class="pl-v">Configuration</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Part 3: Every request and response</h2><a id="user-content-part-3-every-request-and-response" class="anchor" aria-label="Permalink: Part 3: Every request and response" href="#part-3-every-request-and-response"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Imagine we have this route for the home page.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./config/routes.rb
Rails.application.routes.draw do
  root 'home#index' # HomeController#index
end"><pre><span class="pl-c"># ./config/routes.rb</span>
<span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span><span class="pl-kos">.</span><span class="pl-en">routes</span><span class="pl-kos">.</span><span class="pl-en">draw</span> <span class="pl-k">do</span>
  <span class="pl-en">root</span> <span class="pl-s">'home#index'</span> <span class="pl-c"># HomeController#index</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Puma</h3><a id="user-content-puma" class="anchor" aria-label="Permalink: Puma" href="#puma"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When a request is made from client, Puma will process the request in <code>Puma::Server#process_client</code>.</p>
<p dir="auto">If you want to know how Puma enter the method <code>Puma::Server#process_client</code>, please read part 4 or just search 'process_client' in this document.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/puma-3.12.0/lib/puma/server.rb
require 'socket'

module Puma
  # The HTTP Server itself. Serves out a single Rack app.
  #
  # This class is used by the `Puma::Single` and `Puma::Cluster` classes
  # to generate one or more `Puma::Server` instances capable of handling requests.
  # Each Puma process will contain one `Puma::Server` instacne.
  #
  # The `Puma::Server` instance pulls requests from the socket, adds them to a
  # `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.
  #
  # Each `Puma::Server` will have one reactor and one thread pool.
  class Server
    def initialize(app, events=Events.stdio, options={})
      # app: #&lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 
      #        @app = #&lt;YourProject::Application:0x00007fcf160fb120&gt;
      #        @config = #&lt;Puma::Configuration:0x00007fcf169a6c98&gt;         
      #       &gt;
      @app = app
      #...
    end
    
    # Given a connection on +client+, handle the incoming requests.
    #
    # This method support HTTP Keep-Alive so it may, depending on if the client
    # indicates that it supports keep alive, wait for another request before
    # returning.
    #
    def process_client(client, buffer)
      begin
        # ...
        while true
          # Let's step into this line.
          case handle_request(client, buffer) # Will return true in this example.
          when true
            return unless @queue_requests
            buffer.reset

            ThreadPool.clean_thread_locals if clean_thread_locals

            unless client.reset(@status == :run)
              close_socket = false
              client.set_timeout @persistent_timeout
              @reactor.add client
              return
            end
          end
        end
        # ...
      ensure
        buffer.reset
        client.close if close_socket
        #...
      end
    end
    
    # Given the request +env+ from +client+ and a partial request body
    # in +body+, finish reading the body if there is one and invoke
    # the Rack app. Then construct the response and write it back to
    # +client+
    #
    def handle_request(req, lines)
      env = req.env
      # ... 
      # app: #&lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 
      #        @app = #&lt;YourProject::Application:0x00007fcf160fb120&gt;
      #        @config = #&lt;Puma::Configuration:0x00007fcf169a6c98&gt;         
      #       &gt;
      status, headers, res_body = @app.call(env) # Let's step into this line.

      # ...
      return keep_alive
    end    
  end
end"><pre><span class="pl-c"># ./gems/puma-3.12.0/lib/puma/server.rb</span>
<span class="pl-en">require</span> <span class="pl-s">'socket'</span>

<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># The HTTP Server itself. Serves out a single Rack app.</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># This class is used by the `Puma::Single` and `Puma::Cluster` classes</span>
  <span class="pl-c"># to generate one or more `Puma::Server` instances capable of handling requests.</span>
  <span class="pl-c"># Each Puma process will contain one `Puma::Server` instacne.</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># The `Puma::Server` instance pulls requests from the socket, adds them to a</span>
  <span class="pl-c"># `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># Each `Puma::Server` will have one reactor and one thread pool.</span>
  <span class="pl-k">class</span> <span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">events</span><span class="pl-c1">=</span><span class="pl-v">Events</span><span class="pl-kos">.</span><span class="pl-en">stdio</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-c"># app: #&lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 </span>
      <span class="pl-c">#        @app = #&lt;YourProject::Application:0x00007fcf160fb120&gt;</span>
      <span class="pl-c">#        @config = #&lt;Puma::Configuration:0x00007fcf169a6c98&gt;         </span>
      <span class="pl-c">#       &gt;</span>
      <span class="pl-c1">@app</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span>
      <span class="pl-c">#...</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Given a connection on +client+, handle the incoming requests.</span>
    <span class="pl-c">#</span>
    <span class="pl-c"># This method support HTTP Keep-Alive so it may, depending on if the client</span>
    <span class="pl-c"># indicates that it supports keep alive, wait for another request before</span>
    <span class="pl-c"># returning.</span>
    <span class="pl-c">#</span>
    <span class="pl-k">def</span> <span class="pl-en">process_client</span><span class="pl-kos">(</span><span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span><span class="pl-kos">)</span>
      <span class="pl-k">begin</span>
        <span class="pl-c"># ...</span>
        <span class="pl-k">while</span> <span class="pl-c1">true</span>
          <span class="pl-c"># Let's step into this line.</span>
          <span class="pl-k">case</span> <span class="pl-en">handle_request</span><span class="pl-kos">(</span><span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span><span class="pl-kos">)</span> <span class="pl-c"># Will return true in this example.</span>
          <span class="pl-k">when</span> <span class="pl-c1">true</span>
            <span class="pl-k">return</span> <span class="pl-k">unless</span> <span class="pl-c1">@queue_requests</span>
            <span class="pl-s1">buffer</span><span class="pl-kos">.</span><span class="pl-en">reset</span>

            <span class="pl-v">ThreadPool</span><span class="pl-kos">.</span><span class="pl-en">clean_thread_locals</span> <span class="pl-k">if</span> <span class="pl-en">clean_thread_locals</span>

            <span class="pl-k">unless</span> <span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">reset</span><span class="pl-kos">(</span><span class="pl-c1">@status</span> == <span class="pl-pds">:run</span><span class="pl-kos">)</span>
              <span class="pl-s1">close_socket</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>
              <span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">set_timeout</span> <span class="pl-c1">@persistent_timeout</span>
              <span class="pl-c1">@reactor</span><span class="pl-kos">.</span><span class="pl-en">add</span> <span class="pl-s1">client</span>
              <span class="pl-k">return</span>
            <span class="pl-k">end</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>
        <span class="pl-c"># ...</span>
      <span class="pl-k">ensure</span>
        <span class="pl-s1">buffer</span><span class="pl-kos">.</span><span class="pl-en">reset</span>
        <span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">close</span> <span class="pl-k">if</span> <span class="pl-s1">close_socket</span>
        <span class="pl-c">#...</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Given the request +env+ from +client+ and a partial request body</span>
    <span class="pl-c"># in +body+, finish reading the body if there is one and invoke</span>
    <span class="pl-c"># the Rack app. Then construct the response and write it back to</span>
    <span class="pl-c"># +client+</span>
    <span class="pl-c">#</span>
    <span class="pl-k">def</span> <span class="pl-en">handle_request</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">lines</span><span class="pl-kos">)</span>
      <span class="pl-s1">env</span> <span class="pl-c1">=</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">env</span>
      <span class="pl-c"># ... </span>
      <span class="pl-c"># app: #&lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 </span>
      <span class="pl-c">#        @app = #&lt;YourProject::Application:0x00007fcf160fb120&gt;</span>
      <span class="pl-c">#        @config = #&lt;Puma::Configuration:0x00007fcf169a6c98&gt;         </span>
      <span class="pl-c">#       &gt;</span>
      <span class="pl-s1">status</span><span class="pl-kos">,</span> <span class="pl-s1">headers</span><span class="pl-kos">,</span> <span class="pl-s1">res_body</span> <span class="pl-c1">=</span> <span class="pl-c1">@app</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>

      <span class="pl-c"># ...</span>
      <span class="pl-k">return</span> <span class="pl-en">keep_alive</span>
    <span class="pl-k">end</span>    
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/puma-3.12.0/lib/puma/configuration.rb
module Puma
  class Configuration
    class ConfigMiddleware
      def initialize(config, app)
        @config = config
        @app = app
      end

      def call(env)
        env[Const::PUMA_CONFIG] = @config
        # @app: #&lt;YourProject::Application:0x00007fb4b1b4bcf8&gt;
        @app.call(env)
      end
    end
  end
end"><pre><span class="pl-c"># ./gems/puma-3.12.0/lib/puma/configuration.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">Configuration</span>
    <span class="pl-k">class</span> <span class="pl-v">ConfigMiddleware</span>
      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">config</span><span class="pl-kos">,</span> <span class="pl-s1">app</span><span class="pl-kos">)</span>
        <span class="pl-c1">@config</span> <span class="pl-c1">=</span> <span class="pl-s1">config</span>
        <span class="pl-c1">@app</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span>
      <span class="pl-k">end</span>

      <span class="pl-k">def</span> <span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span>
        <span class="pl-s1">env</span><span class="pl-kos">[</span><span class="pl-v">Const</span>::<span class="pl-c1">PUMA_CONFIG</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-c1">@config</span>
        <span class="pl-c"># @app: #&lt;YourProject::Application:0x00007fb4b1b4bcf8&gt;</span>
        <span class="pl-c1">@app</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Rack apps</h3><a id="user-content-rack-apps" class="anchor" aria-label="Permalink: Rack apps" href="#rack-apps"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">As we see when Ruby enter <code>Puma::Configuration::ConfigMiddleware#call</code>, the <code>@app</code> is <code>YourProject::Application</code> instance.</p>
<p dir="auto">It is just the <code>Rails.application</code>.</p>
<p dir="auto">Rack need a <code>call</code> method to process request.</p>
<p dir="auto">Rails defined this <code>call</code> method in <code>Rails::Engine#call</code>, so that <code>YourProject::Application</code> instance will have a <code>call</code> method.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties/lib/rails/engine.rb
module Rails
  class Engine &lt; Railtie
    def call(env) # This method will process every request. It is invoked by Rack. 
      req = build_request env
      app.call req.env # The 'app' method is blow.
    end
    
    def app
      # FYI,
      # caller: [
      # &quot;../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in &lt;module:Finisher&gt;'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'&quot;,
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'&quot;, 
      # &quot;../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'&quot;, 
      # &quot;/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `&lt;top (required)&gt;'&quot;, 
      # &quot;config.ru:2:in `require_relative'&quot;, &quot;config.ru:2:in `block in &lt;main&gt;'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'&quot;, 
      # &quot;config.ru:in `new'&quot;, &quot;config.ru:in `&lt;main&gt;'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'&quot;, 
      # &quot;../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'&quot;,
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'&quot;,
      # &quot;../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'&quot;, 
      # &quot;../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'&quot;,
      # &quot;../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'&quot;,
      # &quot;../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'&quot;, 
      # &quot;../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&lt;top (required)&gt;'&quot;, 
      # &quot;../path/to/your_project/bin/rails:5:in `require'&quot;,
      # &quot;../path/to/your_project/bin/rails:5:in `&lt;main&gt;'&quot;
      # ]
      puts &quot;caller: #{caller.inspect}&quot;
      
      # You may want to know when is the @app first time initialized.
      # It is initialized when 'config.ru' is load by Rack server.
      # Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.
      # When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. 
      @app || @app_build_lock.synchronize { # '@app_build_lock = Mutex.new', so multiple threads share one '@app'.
        @app ||= begin
          # In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). 
          stack = default_middleware_stack # Let's step into this line
          # 'middleware' is a 'middleware_stack'!
          config.middleware = build_middleware.merge_into(stack)
          # FYI, this line is the last line and the result of this line is the return value for @app.
          config.middleware.build(endpoint) # look at this endpoint below. We will enter method `build` later.
        end
      }
      
#  @app: #&lt;Rack::Sendfile:0x00007ff14d905f60 
#          @app=#&lt;ActionDispatch::Static:0x00007ff14d906168 
#                 @app=#&lt;ActionDispatch::Executor:0x00007ff14d9061b8 
#                        ...
#                           @app=#&lt;Rack::ETag:0x00007fa1e540c4f8  
#                                  @app=#&lt;Rack::TempfileReaper:0x00007fa1e540c520 
#                                         @app=#&lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&gt;
#                                 &gt;
#                         ...    
#                        &gt;
#                             
#                 &gt;
#         &gt;
      @app
    end
    
    # Defaults to an ActionDispatch::Routing::RouteSet instance.
    def endpoint
      ActionDispatch::Routing::RouteSet.new_with_config(config)
    end
  end
end"><pre><span class="pl-c"># ./gems/railties/lib/rails/engine.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Engine</span> &lt; <span class="pl-v">Railtie</span>
    <span class="pl-k">def</span> <span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span> <span class="pl-c"># This method will process every request. It is invoked by Rack. </span>
      <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-en">build_request</span> <span class="pl-s1">env</span>
      <span class="pl-en">app</span><span class="pl-kos">.</span><span class="pl-en">call</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">env</span> <span class="pl-c"># The 'app' method is blow.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">app</span>
      <span class="pl-c"># FYI,</span>
      <span class="pl-c"># caller: [</span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in &lt;module:Finisher&gt;'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'",</span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'", </span>
      <span class="pl-c"># "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'", </span>
      <span class="pl-c"># "/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `&lt;top (required)&gt;'", </span>
      <span class="pl-c"># "config.ru:2:in `require_relative'", "config.ru:2:in `block in &lt;main&gt;'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'", </span>
      <span class="pl-c"># "config.ru:in `new'", "config.ru:in `&lt;main&gt;'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'", </span>
      <span class="pl-c"># "../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'",</span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'",</span>
      <span class="pl-c"># "../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'", </span>
      <span class="pl-c"># "../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'",</span>
      <span class="pl-c"># "../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'",</span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'", </span>
      <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&lt;top (required)&gt;'", </span>
      <span class="pl-c"># "../path/to/your_project/bin/rails:5:in `require'",</span>
      <span class="pl-c"># "../path/to/your_project/bin/rails:5:in `&lt;main&gt;'"</span>
      <span class="pl-c"># ]</span>
      <span class="pl-en">puts</span> <span class="pl-s">"caller: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">caller</span><span class="pl-kos">.</span><span class="pl-en">inspect</span><span class="pl-kos">}</span></span>"</span>
      
      <span class="pl-c"># You may want to know when is the @app first time initialized.</span>
      <span class="pl-c"># It is initialized when 'config.ru' is load by Rack server.</span>
      <span class="pl-c"># Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.</span>
      <span class="pl-c"># When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. </span>
      <span class="pl-c1">@app</span> || <span class="pl-c1">@app_build_lock</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-kos">{</span> <span class="pl-c"># '@app_build_lock = Mutex.new', so multiple threads share one '@app'.</span>
        <span class="pl-c1">@app</span> ||= <span class="pl-k">begin</span>
          <span class="pl-c"># In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). </span>
          <span class="pl-s1">stack</span> <span class="pl-c1">=</span> <span class="pl-en">default_middleware_stack</span> <span class="pl-c"># Let's step into this line</span>
          <span class="pl-c"># 'middleware' is a 'middleware_stack'!</span>
          <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">middleware</span> <span class="pl-c1">=</span> <span class="pl-en">build_middleware</span><span class="pl-kos">.</span><span class="pl-en">merge_into</span><span class="pl-kos">(</span><span class="pl-s1">stack</span><span class="pl-kos">)</span>
          <span class="pl-c"># FYI, this line is the last line and the result of this line is the return value for @app.</span>
          <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">middleware</span><span class="pl-kos">.</span><span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-en">endpoint</span><span class="pl-kos">)</span> <span class="pl-c"># look at this endpoint below. We will enter method `build` later.</span>
        <span class="pl-k">end</span>
      <span class="pl-kos">}</span>
      
<span class="pl-c">#  @app: #&lt;Rack::Sendfile:0x00007ff14d905f60 </span>
<span class="pl-c">#          @app=#&lt;ActionDispatch::Static:0x00007ff14d906168 </span>
<span class="pl-c">#                 @app=#&lt;ActionDispatch::Executor:0x00007ff14d9061b8 </span>
<span class="pl-c">#                        ...</span>
<span class="pl-c">#                           @app=#&lt;Rack::ETag:0x00007fa1e540c4f8  </span>
<span class="pl-c">#                                  @app=#&lt;Rack::TempfileReaper:0x00007fa1e540c520 </span>
<span class="pl-c">#                                         @app=#&lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&gt;</span>
<span class="pl-c">#                                 &gt;</span>
<span class="pl-c">#                         ...    </span>
<span class="pl-c">#                        &gt;</span>
<span class="pl-c">#                             </span>
<span class="pl-c">#                 &gt;</span>
<span class="pl-c">#         &gt;</span>
      <span class="pl-c1">@app</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Defaults to an ActionDispatch::Routing::RouteSet instance.</span>
    <span class="pl-k">def</span> <span class="pl-en">endpoint</span>
      <span class="pl-v">ActionDispatch</span>::<span class="pl-v">Routing</span>::<span class="pl-v">RouteSet</span><span class="pl-kos">.</span><span class="pl-en">new_with_config</span><span class="pl-kos">(</span><span class="pl-en">config</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties/lib/rails/application...
module Rails
  class Application &lt; Engine
    def default_middleware_stack
      default_stack = DefaultMiddlewareStack.new(self, config, paths)
      default_stack.build_stack # Let's step into this line.
    end
    
    class DefaultMiddlewareStack
      attr_reader :config, :paths, :app

      def initialize(app, config, paths)
        @app = app
        @config = config
        @paths = paths
      end

      def build_stack
        ActionDispatch::MiddlewareStack.new do |middleware|
          if config.force_ssl
            middleware.use ::ActionDispatch::SSL, config.ssl_options
          end

          middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header

          if config.public_file_server.enabled
            headers = config.public_file_server.headers || {}

            middleware.use ::ActionDispatch::Static, paths[&quot;public&quot;].first, index: config.public_file_server.index_name, headers: headers
          end

          if rack_cache = load_rack_cache
            require &quot;action_dispatch/http/rack_cache&quot;
            middleware.use ::Rack::Cache, rack_cache
          end

          if config.allow_concurrency == false
            # User has explicitly opted out of concurrent request
            # handling: presumably their code is not threadsafe

            middleware.use ::Rack::Lock
          end

          middleware.use ::ActionDispatch::Executor, app.executor

          middleware.use ::Rack::Runtime
          middleware.use ::Rack::MethodOverride unless config.api_only
          middleware.use ::ActionDispatch::RequestId
          middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies

          middleware.use ::Rails::Rack::Logger, config.log_tags
          middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
          middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format

          unless config.cache_classes
            middleware.use ::ActionDispatch::Reloader, app.reloader
          end

          middleware.use ::ActionDispatch::Callbacks
          middleware.use ::ActionDispatch::Cookies unless config.api_only

          if !config.api_only &amp;&amp; config.session_store
            if config.force_ssl &amp;&amp; config.ssl_options.fetch(:secure_cookies, true) &amp;&amp; !config.session_options.key?(:secure)
              config.session_options[:secure] = true
            end
            middleware.use config.session_store, config.session_options
            middleware.use ::ActionDispatch::Flash
          end

          unless config.api_only
            middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
          end

          middleware.use ::Rack::Head
          middleware.use ::Rack::ConditionalGet
          middleware.use ::Rack::ETag, &quot;no-cache&quot;

          middleware.use ::Rack::TempfileReaper unless config.api_only
        end
       end
     end
  end
end"><pre><span class="pl-c"># ./gems/railties/lib/rails/application...</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Application</span> &lt; <span class="pl-v">Engine</span>
    <span class="pl-k">def</span> <span class="pl-en">default_middleware_stack</span>
      <span class="pl-s1">default_stack</span> <span class="pl-c1">=</span> <span class="pl-v">DefaultMiddlewareStack</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">,</span> <span class="pl-en">paths</span><span class="pl-kos">)</span>
      <span class="pl-s1">default_stack</span><span class="pl-kos">.</span><span class="pl-en">build_stack</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">class</span> <span class="pl-v">DefaultMiddlewareStack</span>
      <span class="pl-en">attr_reader</span> <span class="pl-pds">:config</span><span class="pl-kos">,</span> <span class="pl-pds">:paths</span><span class="pl-kos">,</span> <span class="pl-pds">:app</span>

      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">,</span> <span class="pl-s1">paths</span><span class="pl-kos">)</span>
        <span class="pl-c1">@app</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span>
        <span class="pl-c1">@config</span> <span class="pl-c1">=</span> <span class="pl-s1">config</span>
        <span class="pl-c1">@paths</span> <span class="pl-c1">=</span> <span class="pl-s1">paths</span>
      <span class="pl-k">end</span>

      <span class="pl-k">def</span> <span class="pl-en">build_stack</span>
        <span class="pl-v">ActionDispatch</span>::<span class="pl-v">MiddlewareStack</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-k">do</span> |<span class="pl-s1">middleware</span>|
          <span class="pl-k">if</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">force_ssl</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-c1">SSL</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">ssl_options</span>
          <span class="pl-k">end</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">Sendfile</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">action_dispatch</span><span class="pl-kos">.</span><span class="pl-en">x_sendfile_header</span>

          <span class="pl-k">if</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">public_file_server</span><span class="pl-kos">.</span><span class="pl-en">enabled</span>
            <span class="pl-s1">headers</span> <span class="pl-c1">=</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">public_file_server</span><span class="pl-kos">.</span><span class="pl-s1">headers</span> || <span class="pl-kos">{</span><span class="pl-kos">}</span>

            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Static</span><span class="pl-kos">,</span> <span class="pl-en">paths</span><span class="pl-kos">[</span><span class="pl-s">"public"</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">first</span><span class="pl-kos">,</span> <span class="pl-pds">index</span>: <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">public_file_server</span><span class="pl-kos">.</span><span class="pl-en">index_name</span><span class="pl-kos">,</span> <span class="pl-pds">headers</span>: <span class="pl-s1">headers</span>
          <span class="pl-k">end</span>

          <span class="pl-k">if</span> <span class="pl-s1">rack_cache</span> <span class="pl-c1">=</span> <span class="pl-en">load_rack_cache</span>
            <span class="pl-en">require</span> <span class="pl-s">"action_dispatch/http/rack_cache"</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">Cache</span><span class="pl-kos">,</span> <span class="pl-s1">rack_cache</span>
          <span class="pl-k">end</span>

          <span class="pl-k">if</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">allow_concurrency</span> == <span class="pl-c1">false</span>
            <span class="pl-c"># User has explicitly opted out of concurrent request</span>
            <span class="pl-c"># handling: presumably their code is not threadsafe</span>

            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">Lock</span>
          <span class="pl-k">end</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Executor</span><span class="pl-kos">,</span> <span class="pl-en">app</span><span class="pl-kos">.</span><span class="pl-en">executor</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">Runtime</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">MethodOverride</span> <span class="pl-k">unless</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">api_only</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">RequestId</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">RemoteIp</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">action_dispatch</span><span class="pl-kos">.</span><span class="pl-en">ip_spoofing_check</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">action_dispatch</span><span class="pl-kos">.</span><span class="pl-en">trusted_proxies</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rails</span>::<span class="pl-v">Rack</span>::<span class="pl-v">Logger</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">log_tags</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">ShowExceptions</span><span class="pl-kos">,</span> <span class="pl-en">show_exceptions_app</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">DebugExceptions</span><span class="pl-kos">,</span> <span class="pl-en">app</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">debug_exception_response_format</span>

          <span class="pl-k">unless</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">cache_classes</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Reloader</span><span class="pl-kos">,</span> <span class="pl-en">app</span><span class="pl-kos">.</span><span class="pl-en">reloader</span>
          <span class="pl-k">end</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Callbacks</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Cookies</span> <span class="pl-k">unless</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">api_only</span>

          <span class="pl-k">if</span> !<span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">api_only</span> &amp;&amp; <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">session_store</span>
            <span class="pl-k">if</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">force_ssl</span> &amp;&amp; <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">ssl_options</span><span class="pl-kos">.</span><span class="pl-en">fetch</span><span class="pl-kos">(</span><span class="pl-pds">:secure_cookies</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span> &amp;&amp; !<span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">session_options</span><span class="pl-kos">.</span><span class="pl-en">key?</span><span class="pl-kos">(</span><span class="pl-pds">:secure</span><span class="pl-kos">)</span>
              <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">session_options</span><span class="pl-kos">[</span><span class="pl-pds">:secure</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>
            <span class="pl-k">end</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">session_store</span><span class="pl-kos">,</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">session_options</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">Flash</span>
          <span class="pl-k">end</span>

          <span class="pl-k">unless</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">api_only</span>
            <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">ActionDispatch</span>::<span class="pl-v">ContentSecurityPolicy</span>::<span class="pl-v">Middleware</span>
          <span class="pl-k">end</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">Head</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">ConditionalGet</span>
          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">ETag</span><span class="pl-kos">,</span> <span class="pl-s">"no-cache"</span>

          <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">use</span> ::<span class="pl-v">Rack</span>::<span class="pl-v">TempfileReaper</span> <span class="pl-k">unless</span> <span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">api_only</span>
        <span class="pl-k">end</span>
       <span class="pl-k">end</span>
     <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb
module ActionDispatch
  class MiddlewareStack
    def use(klass, *args, &amp;block)
      middlewares.push(build_middleware(klass, args, block))
    end
    
    def build_middleware(klass, args, block)
      Middleware.new(klass, args, block)
    end    
    
    def build(app = Proc.new)
      # See Enumerable#inject for more information.
      return_val = middlewares.freeze.reverse.inject(app) do |a, middleware|
        # a: app, and will be changed when iterating
        # middleware: #&lt;ActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8&gt;, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating
        middleware.build(a) # Let's step into this line.
      end

      return_val
    end    
    
    class Middleware
      def initialize(klass, args, block)
        @klass = klass
        @args  = args
        @block = block
      end

      def build(app)
        # klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.
        # It's typical Rack app to use these middlewares.
        # See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. 
        klass.new(app, *args, &amp;block)
      end      
    end
  end
end"><pre><span class="pl-c"># ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionDispatch</span>
  <span class="pl-k">class</span> <span class="pl-v">MiddlewareStack</span>
    <span class="pl-k">def</span> <span class="pl-en">use</span><span class="pl-kos">(</span><span class="pl-s1">klass</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-en">middlewares</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span><span class="pl-en">build_middleware</span><span class="pl-kos">(</span><span class="pl-s1">klass</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">block</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">build_middleware</span><span class="pl-kos">(</span><span class="pl-s1">klass</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-v">Middleware</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">klass</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">block</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>    
    
    <span class="pl-k">def</span> <span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">Proc</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">)</span>
      <span class="pl-c"># See Enumerable#inject for more information.</span>
      <span class="pl-s1">return_val</span> <span class="pl-c1">=</span> <span class="pl-en">middlewares</span><span class="pl-kos">.</span><span class="pl-en">freeze</span><span class="pl-kos">.</span><span class="pl-en">reverse</span><span class="pl-kos">.</span><span class="pl-en">inject</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">middleware</span>|
        <span class="pl-c"># a: app, and will be changed when iterating</span>
        <span class="pl-c"># middleware: #&lt;ActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8&gt;, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating</span>
        <span class="pl-s1">middleware</span><span class="pl-kos">.</span><span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-s1">a</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>

      <span class="pl-s1">return_val</span>
    <span class="pl-k">end</span>    
    
    <span class="pl-k">class</span> <span class="pl-v">Middleware</span>
      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">klass</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">block</span><span class="pl-kos">)</span>
        <span class="pl-c1">@klass</span> <span class="pl-c1">=</span> <span class="pl-s1">klass</span>
        <span class="pl-c1">@args</span>  <span class="pl-c1">=</span> <span class="pl-s1">args</span>
        <span class="pl-c1">@block</span> <span class="pl-c1">=</span> <span class="pl-s1">block</span>
      <span class="pl-k">end</span>

      <span class="pl-k">def</span> <span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">)</span>
        <span class="pl-c"># klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.</span>
        <span class="pl-c"># It's typical Rack app to use these middlewares.</span>
        <span class="pl-c"># See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. </span>
        <span class="pl-en">klass</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> *<span class="pl-en">args</span><span class="pl-kos">,</span> &amp;<span class="pl-en">block</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>      
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">The core app: ActionDispatch::Routing::RouteSet instance</h3><a id="user-content-the-core-app-actiondispatchroutingrouteset-instance" class="anchor" aria-label="Permalink: The core app: ActionDispatch::Routing::RouteSet instance" href="#the-core-app-actiondispatchroutingrouteset-instance"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Paste again FYI. 
#  @app: #&lt;Rack::Sendfile:0x00007ff14d905f60 
#          @app=#&lt;ActionDispatch::Static:0x00007ff14d906168 
#                 @app=#&lt;ActionDispatch::Executor:0x00007ff14d9061b8 
#                        ...
#                           @app=#&lt;Rack::ETag:0x00007fa1e540c4f8  
#                                  @app=#&lt;Rack::TempfileReaper:0x00007fa1e540c520 
#                                         @app=#&lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&gt;
#                                 &gt;
#                         ...    
#                        &gt;
#                             
#                 &gt;
#         &gt;"><pre><span class="pl-c"># Paste again FYI. </span>
<span class="pl-c">#  @app: #&lt;Rack::Sendfile:0x00007ff14d905f60 </span>
<span class="pl-c">#          @app=#&lt;ActionDispatch::Static:0x00007ff14d906168 </span>
<span class="pl-c">#                 @app=#&lt;ActionDispatch::Executor:0x00007ff14d9061b8 </span>
<span class="pl-c">#                        ...</span>
<span class="pl-c">#                           @app=#&lt;Rack::ETag:0x00007fa1e540c4f8  </span>
<span class="pl-c">#                                  @app=#&lt;Rack::TempfileReaper:0x00007fa1e540c520 </span>
<span class="pl-c">#                                         @app=#&lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&gt;</span>
<span class="pl-c">#                                 &gt;</span>
<span class="pl-c">#                         ...    </span>
<span class="pl-c">#                        &gt;</span>
<span class="pl-c">#                             </span>
<span class="pl-c">#                 &gt;</span>
<span class="pl-c">#         &gt;</span></pre></div>
<p dir="auto">As we see in the Rack middleware stack, the last @app is</p>
<p dir="auto"><code>@app=#&lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&gt;</code></p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb
module ActionDispatch
  module Routing
    class RouteSet
      def initialize(config = DEFAULT_CONFIG)
        @set    = Journey::Routes.new
        @router = Journey::Router.new(@set)
      end
    
      def call(env)
        req = make_request(env) # return ActionDispatch::Request.new(env)
        req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
        @router.serve(req) # Let's step into this line.
      end
    end
  end
  
# ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  
  module Journey
    class Router
      class RoutingError &lt; ::StandardError
      end
    
      attr_accessor :routes
        
      def initialize(routes)
        @routes = routes
      end
        
      def serve(req)
        find_routes(req).each do |match, parameters, route| # Let's step into 'find_routes'
          set_params  = req.path_parameters
          path_info   = req.path_info
          script_name = req.script_name
        
          unless route.path.anchored
            req.script_name = (script_name.to_s + match.to_s).chomp(&quot;/&quot;)
            req.path_info = match.post_match
            req.path_info = &quot;/&quot; + req.path_info unless req.path_info.start_with? &quot;/&quot;
          end
        
          parameters = route.defaults.merge parameters.transform_values { |val|
            val.dup.force_encoding(::Encoding::UTF_8)
          }
        
          req.path_parameters = set_params.merge parameters
        
          # 'route' is an instance of ActionDispatch::Journey::Route. 
          # 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.
          status, headers, body = route.app.serve(req) # Let's step into method 'serve'
        
          if &quot;pass&quot; == headers[&quot;X-Cascade&quot;]
            req.script_name     = script_name
            req.path_info       = path_info
            req.path_parameters = set_params
            next
          end
        
          return [status, headers, body]
        end
    
        [404, { &quot;X-Cascade&quot; =&gt; &quot;pass&quot; }, [&quot;Not Found&quot;]]
      end
      
      def find_routes(req)
        routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|
          r.path.match(req.path_info)
        }

        routes =
          if req.head?
            match_head_routes(routes, req)
          else
            match_routes(routes, req)
          end

        routes.sort_by!(&amp;:precedence)

        routes.map! { |r|
          match_data = r.path.match(req.path_info)
          path_parameters = {}
          match_data.names.zip(match_data.captures) { |name, val|
            path_parameters[name.to_sym] = Utils.unescape_uri(val) if val
          }
          [match_data, path_parameters, r]
        }
      end

    end
  end
end

# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb
module ActionDispatch
  module Routing
    class RouteSet
      class Dispatcher &lt; Routing::Endpoint
        def serve(req)
          params     = req.path_parameters # params: { action: 'index', controller: 'home' }
          controller = controller(req) # controller: HomeController
          # The definition of 'make_response!' is 
          # ActionDispatch::Response.create.tap { |res| res.request = request; }
          res        = controller.make_response!(req) 
          dispatch(controller, params[:action], req, res) # Let's step into this line.
        rescue ActionController::RoutingError
          if @raise_on_name_error
            raise
          else
            return [404, { &quot;X-Cascade&quot; =&gt; &quot;pass&quot; }, []]
          end
        end
        
        private
        
        def controller(req)
          req.controller_class
        rescue NameError =&gt; e
          raise ActionController::RoutingError, e.message, e.backtrace
        end

        def dispatch(controller, action, req, res)
          controller.dispatch(action, req, res) # Let's step into this line.
        end
      end
    end
  end    
end

# ./gems/actionpack-5.2.2/lib/action_controller/metal.rb
module ActionController
  class Metal &lt; AbstractController::Base
    abstract!
    
    def self.controller_name
      @controller_name ||= name.demodulize.sub(/Controller$/, &quot;&quot;).underscore
    end

    def self.make_response!(request)
      ActionDispatch::Response.new.tap do |res|
        res.request = request
      end
    end
    
    class_attribute :middleware_stack, default: ActionController::MiddlewareStack.new
    
    def self.inherited(base)
      base.middleware_stack = middleware_stack.dup
      super
    end
    
    # Direct dispatch to the controller. Instantiates the controller, then
    # executes the action named +name+.
    def self.dispatch(name, req, res)
      if middleware_stack.any?
        middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
      else
        # 'self' is HomeController, so for this line Rails will new a HomeController instance.  
        # Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.
        # These are some typical superclasses of HomeController. 
        # HomeController
        # &lt; ApplicationController
        # &lt; ActionController::Base
        # &lt; ActiveRecord::Railties::ControllerRuntime (module included)
        # &lt; ActionController::Instrumentation (module included)
        # &lt; ActionController::Rescue (module included)
        # &lt; AbstractController::Callbacks (module included)
        # &lt; ActionController::ImplicitRender (module included)
        # &lt; ActionController::BasicImplicitRender (module included)
        # &lt; ActionController::Renderers (module included) 
        # &lt; ActionController::Rendering (module included) 
        # &lt; ActionView::Layouts (module included) 
        # &lt; ActionView::Rendering (module included)
        # &lt; ActionDispatch::Routing::UrlFor (module included) 
        # &lt; AbstractController::Rendering (module included)
        # &lt; ActionController::Metal
        # &lt; AbstractController::Base
        new.dispatch(name, req, res) # Let's step into this line.
      end
    end
    
    def dispatch(name, request, response)
      set_request!(request)
      set_response!(response)
      process(name) # Let's step into this line.
      request.commit_flash
      to_a
    end
    
    def to_a
      response.to_a
    end
  end
end

# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb
module AbstractController
  class Base
    def process(action, *args)
      @_action_name = action.to_s

      unless action_name = _find_action_name(@_action_name)
        raise ActionNotFound, &quot;The action '#{action}' could not be found for #{self.class.name}&quot;
      end

      @_response_body = nil

      # action_name: 'index'
      process_action(action_name, *args) # Let's step into this line.
    end
  end
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb
module ActionController
  module Instrumentation
    def process_action(*args)
      raw_payload = {
        controller: self.class.name,
        action: action_name,
        params: request.filtered_parameters,
        headers: request.headers,
        format: request.format.ref,
        method: request.request_method,
        path: request.fullpath
      }
    
      ActiveSupport::Notifications.instrument(&quot;start_processing.action_controller&quot;, raw_payload.dup)
    
      ActiveSupport::Notifications.instrument(&quot;process_action.action_controller&quot;, raw_payload) do |payload|
        begin
          # self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;
          result = super # Let's step into this line.
          payload[:status] = response.status
          result
        ensure
          append_info_to_payload(payload)
        end
      end
    end
  end
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb
module ActionController
  module Rescue
    def process_action(*args)
      super # Let's step into this line.
    rescue Exception =&gt; exception
      request.env[&quot;action_dispatch.show_detailed_exceptions&quot;] ||= show_detailed_exceptions?
      rescue_with_handler(exception) || raise
    end
  end  
end

# .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb
module AbstractController
  # = Abstract Controller Callbacks
  #
  # Abstract Controller provides hooks during the life cycle of a controller action.
  # Callbacks allow you to trigger logic during this cycle. Available callbacks are:
  #
  # * &lt;tt&gt;after_action&lt;/tt&gt;
  # * &lt;tt&gt;before_action&lt;/tt&gt;
  # * &lt;tt&gt;skip_before_action&lt;/tt&gt;
  # * ...
  module Callbacks
    def process_action(*args)
      run_callbacks(:process_action) do
        # self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;
        super # Let's step into this line.
      end
    end
  end
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb
module ActionController
  module Rendering
    def process_action(*)
      self.formats = request.formats.map(&amp;:ref).compact
      super # Let's step into this line.
    end
  end
end

# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb
module AbstractController
  class Base
    def process_action(method_name, *args)
      # self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;, method_name: 'index'
      # In the end, method 'send_action' is method 'send' by `alias send_action send` 
      send_action(method_name, *args)
    end

    alias send_action send
  end
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb
module ActionController
  module BasicImplicitRender
    def send_action(method, *args)
      # self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;, method_name: 'index'    
      # Because 'send_action' is an alias of 'send',  
      # self.send('index', *args) will goto HomeController#index.
      x = super
      # performed?: false (for this example)
      x.tap { default_render unless performed? } # Let's step into 'default_render' later.
    end
  end
end

# ./your_project/app/controllers/home_controller.rb
class HomeController &lt; ApplicationController
  # Will go back to BasicImplicitRender#send_action when method 'index' is done.
  def index
    # Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?
    # I will answer this question later. 
    @users = User.all.pluck(:id, :name)
  end
end"><pre><span class="pl-c"># ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionDispatch</span>
  <span class="pl-k">module</span> <span class="pl-v">Routing</span>
    <span class="pl-k">class</span> <span class="pl-v">RouteSet</span>
      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">config</span> <span class="pl-c1">=</span> <span class="pl-c1">DEFAULT_CONFIG</span><span class="pl-kos">)</span>
        <span class="pl-c1">@set</span>    <span class="pl-c1">=</span> <span class="pl-v">Journey</span>::<span class="pl-v">Routes</span><span class="pl-kos">.</span><span class="pl-en">new</span>
        <span class="pl-c1">@router</span> <span class="pl-c1">=</span> <span class="pl-v">Journey</span>::<span class="pl-v">Router</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@set</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
    
      <span class="pl-k">def</span> <span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span>
        <span class="pl-s1">req</span> <span class="pl-c1">=</span> <span class="pl-en">make_request</span><span class="pl-kos">(</span><span class="pl-s1">env</span><span class="pl-kos">)</span> <span class="pl-c"># return ActionDispatch::Request.new(env)</span>
        <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_info</span> <span class="pl-c1">=</span> <span class="pl-v">Journey</span>::<span class="pl-v">Router</span>::<span class="pl-v">Utils</span><span class="pl-kos">.</span><span class="pl-en">normalize_path</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_info</span><span class="pl-kos">)</span>
        <span class="pl-c1">@router</span><span class="pl-kos">.</span><span class="pl-en">serve</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
  
<span class="pl-c"># ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  </span>
  <span class="pl-k">module</span> <span class="pl-v">Journey</span>
    <span class="pl-k">class</span> <span class="pl-v">Router</span>
      <span class="pl-k">class</span> <span class="pl-v">RoutingError</span> &lt; ::<span class="pl-v">StandardError</span>
      <span class="pl-k">end</span>
    
      <span class="pl-en">attr_accessor</span> <span class="pl-pds">:routes</span>
        
      <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">routes</span><span class="pl-kos">)</span>
        <span class="pl-c1">@routes</span> <span class="pl-c1">=</span> <span class="pl-s1">routes</span>
      <span class="pl-k">end</span>
        
      <span class="pl-k">def</span> <span class="pl-en">serve</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span>
        <span class="pl-en">find_routes</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">match</span><span class="pl-kos">,</span> <span class="pl-s1">parameters</span><span class="pl-kos">,</span> <span class="pl-s1">route</span>| <span class="pl-c"># Let's step into 'find_routes'</span>
          <span class="pl-s1">set_params</span>  <span class="pl-c1">=</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_parameters</span>
          <span class="pl-s1">path_info</span>   <span class="pl-c1">=</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span>
          <span class="pl-s1">script_name</span> <span class="pl-c1">=</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">script_name</span>
        
          <span class="pl-k">unless</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">path</span><span class="pl-kos">.</span><span class="pl-en">anchored</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">script_name</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">script_name</span><span class="pl-kos">.</span><span class="pl-en">to_s</span> + <span class="pl-s1">match</span><span class="pl-kos">.</span><span class="pl-en">to_s</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">chomp</span><span class="pl-kos">(</span><span class="pl-s">"/"</span><span class="pl-kos">)</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span> <span class="pl-c1">=</span> <span class="pl-s1">match</span><span class="pl-kos">.</span><span class="pl-en">post_match</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span> <span class="pl-c1">=</span> <span class="pl-s">"/"</span> + <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span> <span class="pl-k">unless</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span><span class="pl-kos">.</span><span class="pl-en">start_with?</span> <span class="pl-s">"/"</span>
          <span class="pl-k">end</span>
        
          <span class="pl-s1">parameters</span> <span class="pl-c1">=</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">defaults</span><span class="pl-kos">.</span><span class="pl-en">merge</span> <span class="pl-s1">parameters</span><span class="pl-kos">.</span><span class="pl-en">transform_values</span> <span class="pl-kos">{</span> |<span class="pl-s1">val</span>|
            <span class="pl-s1">val</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-kos">.</span><span class="pl-en">force_encoding</span><span class="pl-kos">(</span>::<span class="pl-v">Encoding</span>::<span class="pl-c1">UTF_8</span><span class="pl-kos">)</span>
          <span class="pl-kos">}</span>
        
          <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_parameters</span> <span class="pl-c1">=</span> <span class="pl-s1">set_params</span><span class="pl-kos">.</span><span class="pl-en">merge</span> <span class="pl-s1">parameters</span>
        
          <span class="pl-c"># 'route' is an instance of ActionDispatch::Journey::Route. </span>
          <span class="pl-c"># 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.</span>
          <span class="pl-s1">status</span><span class="pl-kos">,</span> <span class="pl-s1">headers</span><span class="pl-kos">,</span> <span class="pl-s1">body</span> <span class="pl-c1">=</span> <span class="pl-s1">route</span><span class="pl-kos">.</span><span class="pl-en">app</span><span class="pl-kos">.</span><span class="pl-en">serve</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into method 'serve'</span>
        
          <span class="pl-k">if</span> <span class="pl-s">"pass"</span> == <span class="pl-s1">headers</span><span class="pl-kos">[</span><span class="pl-s">"X-Cascade"</span><span class="pl-kos">]</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">script_name</span>     <span class="pl-c1">=</span> <span class="pl-s1">script_name</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-s1">path_info</span>       <span class="pl-c1">=</span> <span class="pl-s1">path_info</span>
            <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_parameters</span> <span class="pl-c1">=</span> <span class="pl-s1">set_params</span>
            <span class="pl-k">next</span>
          <span class="pl-k">end</span>
        
          <span class="pl-k">return</span> <span class="pl-kos">[</span><span class="pl-s1">status</span><span class="pl-kos">,</span> <span class="pl-s1">headers</span><span class="pl-kos">,</span> <span class="pl-s1">body</span><span class="pl-kos">]</span>
        <span class="pl-k">end</span>
    
        <span class="pl-kos">[</span><span class="pl-c1">404</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s">"X-Cascade"</span> <span class="pl-c1">=&gt;</span> <span class="pl-s">"pass"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">"Not Found"</span><span class="pl-kos">]</span><span class="pl-kos">]</span>
      <span class="pl-k">end</span>
      
      <span class="pl-k">def</span> <span class="pl-en">find_routes</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span>
        <span class="pl-s1">routes</span> <span class="pl-c1">=</span> <span class="pl-en">filter_routes</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_info</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">concat</span> <span class="pl-en">custom_routes</span><span class="pl-kos">.</span><span class="pl-en">find_all</span> <span class="pl-kos">{</span> |<span class="pl-s1">r</span>|
          <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-en">path</span><span class="pl-kos">.</span><span class="pl-en">match</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_info</span><span class="pl-kos">)</span>
        <span class="pl-kos">}</span>

        <span class="pl-s1">routes</span> <span class="pl-c1">=</span>
          <span class="pl-k">if</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">head?</span>
            <span class="pl-en">match_head_routes</span><span class="pl-kos">(</span><span class="pl-s1">routes</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">)</span>
          <span class="pl-k">else</span>
            <span class="pl-en">match_routes</span><span class="pl-kos">(</span><span class="pl-s1">routes</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">)</span>
          <span class="pl-k">end</span>

        <span class="pl-s1">routes</span><span class="pl-kos">.</span><span class="pl-en">sort_by!</span><span class="pl-kos">(</span>&amp;<span class="pl-pds">:precedence</span><span class="pl-kos">)</span>

        <span class="pl-s1">routes</span><span class="pl-kos">.</span><span class="pl-en">map!</span> <span class="pl-kos">{</span> |<span class="pl-s1">r</span>|
          <span class="pl-s1">match_data</span> <span class="pl-c1">=</span> <span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-en">path</span><span class="pl-kos">.</span><span class="pl-en">match</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_info</span><span class="pl-kos">)</span>
          <span class="pl-s1">path_parameters</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
          <span class="pl-s1">match_data</span><span class="pl-kos">.</span><span class="pl-en">names</span><span class="pl-kos">.</span><span class="pl-en">zip</span><span class="pl-kos">(</span><span class="pl-s1">match_data</span><span class="pl-kos">.</span><span class="pl-en">captures</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> |<span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">val</span>|
            <span class="pl-s1">path_parameters</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">.</span><span class="pl-en">to_sym</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-v">Utils</span><span class="pl-kos">.</span><span class="pl-en">unescape_uri</span><span class="pl-kos">(</span><span class="pl-s1">val</span><span class="pl-kos">)</span> <span class="pl-k">if</span> <span class="pl-s1">val</span>
          <span class="pl-kos">}</span>
          <span class="pl-kos">[</span><span class="pl-s1">match_data</span><span class="pl-kos">,</span> <span class="pl-s1">path_parameters</span><span class="pl-kos">,</span> <span class="pl-s1">r</span><span class="pl-kos">]</span>
        <span class="pl-kos">}</span>
      <span class="pl-k">end</span>

    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionDispatch</span>
  <span class="pl-k">module</span> <span class="pl-v">Routing</span>
    <span class="pl-k">class</span> <span class="pl-v">RouteSet</span>
      <span class="pl-k">class</span> <span class="pl-v">Dispatcher</span> &lt; <span class="pl-v">Routing</span>::<span class="pl-v">Endpoint</span>
        <span class="pl-k">def</span> <span class="pl-en">serve</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span>
          <span class="pl-s1">params</span>     <span class="pl-c1">=</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">path_parameters</span> <span class="pl-c"># params: { action: 'index', controller: 'home' }</span>
          <span class="pl-s1">controller</span> <span class="pl-c1">=</span> <span class="pl-s1">controller</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span> <span class="pl-c"># controller: HomeController</span>
          <span class="pl-c"># The definition of 'make_response!' is </span>
          <span class="pl-c"># ActionDispatch::Response.create.tap { |res| res.request = request; }</span>
          <span class="pl-s1">res</span>        <span class="pl-c1">=</span> <span class="pl-s1">controller</span><span class="pl-kos">.</span><span class="pl-en">make_response!</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span> 
          <span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">controller</span><span class="pl-kos">,</span> <span class="pl-s1">params</span><span class="pl-kos">[</span><span class="pl-pds">:action</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-k">rescue</span> <span class="pl-v">ActionController</span>::<span class="pl-v">RoutingError</span>
          <span class="pl-k">if</span> <span class="pl-c1">@raise_on_name_error</span>
            <span class="pl-en">raise</span>
          <span class="pl-k">else</span>
            <span class="pl-k">return</span> <span class="pl-kos">[</span><span class="pl-c1">404</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s">"X-Cascade"</span> <span class="pl-c1">=&gt;</span> <span class="pl-s">"pass"</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">]</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>
        
        <span class="pl-k">private</span>
        
        <span class="pl-k">def</span> <span class="pl-en">controller</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">)</span>
          <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">controller_class</span>
        <span class="pl-k">rescue</span> <span class="pl-v">NameError</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">e</span>
          <span class="pl-en">raise</span> <span class="pl-v">ActionController</span>::<span class="pl-v">RoutingError</span><span class="pl-kos">,</span> <span class="pl-en">e</span><span class="pl-kos">.</span><span class="pl-en">message</span><span class="pl-kos">,</span> <span class="pl-en">e</span><span class="pl-kos">.</span><span class="pl-en">backtrace</span>
        <span class="pl-k">end</span>

        <span class="pl-k">def</span> <span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">controller</span><span class="pl-kos">,</span> <span class="pl-s1">action</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span>
          <span class="pl-s1">controller</span><span class="pl-kos">.</span><span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">action</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>    
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/actionpack-5.2.2/lib/action_controller/metal.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">class</span> <span class="pl-v">Metal</span> &lt; <span class="pl-v">AbstractController</span>::<span class="pl-v">Base</span>
    <span class="pl-en">abstract!</span>
    
    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">controller_name</span>
      <span class="pl-c1">@controller_name</span> ||= <span class="pl-en">name</span><span class="pl-kos">.</span><span class="pl-en">demodulize</span><span class="pl-kos">.</span><span class="pl-en">sub</span><span class="pl-kos">(</span><span class="pl-sr">/Controller$/</span><span class="pl-kos">,</span> <span class="pl-s">""</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">underscore</span>
    <span class="pl-k">end</span>

    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">make_response!</span><span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">)</span>
      <span class="pl-v">ActionDispatch</span>::<span class="pl-v">Response</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">.</span><span class="pl-en">tap</span> <span class="pl-k">do</span> |<span class="pl-s1">res</span>|
        <span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-s1">request</span> <span class="pl-c1">=</span> <span class="pl-s1">request</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-en">class_attribute</span> <span class="pl-pds">:middleware_stack</span><span class="pl-kos">,</span> <span class="pl-pds">default</span>: <span class="pl-v">ActionController</span>::<span class="pl-v">MiddlewareStack</span><span class="pl-kos">.</span><span class="pl-en">new</span>
    
    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">inherited</span><span class="pl-kos">(</span><span class="pl-s1">base</span><span class="pl-kos">)</span>
      <span class="pl-s1">base</span><span class="pl-kos">.</span><span class="pl-en">middleware_stack</span> <span class="pl-c1">=</span> <span class="pl-en">middleware_stack</span><span class="pl-kos">.</span><span class="pl-en">dup</span>
      <span class="pl-smi">super</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Direct dispatch to the controller. Instantiates the controller, then</span>
    <span class="pl-c"># executes the action named +name+.</span>
    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span>
      <span class="pl-k">if</span> <span class="pl-en">middleware_stack</span><span class="pl-kos">.</span><span class="pl-en">any?</span>
        <span class="pl-en">middleware_stack</span><span class="pl-kos">.</span><span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> |<span class="pl-s1">env</span>| <span class="pl-en">new</span><span class="pl-kos">.</span><span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-kos">}</span><span class="pl-kos">.</span><span class="pl-en">call</span> <span class="pl-s1">req</span><span class="pl-kos">.</span><span class="pl-en">env</span>
      <span class="pl-k">else</span>
        <span class="pl-c"># 'self' is HomeController, so for this line Rails will new a HomeController instance.  </span>
        <span class="pl-c"># Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.</span>
        <span class="pl-c"># These are some typical superclasses of HomeController. </span>
        <span class="pl-c"># HomeController</span>
        <span class="pl-c"># &lt; ApplicationController</span>
        <span class="pl-c"># &lt; ActionController::Base</span>
        <span class="pl-c"># &lt; ActiveRecord::Railties::ControllerRuntime (module included)</span>
        <span class="pl-c"># &lt; ActionController::Instrumentation (module included)</span>
        <span class="pl-c"># &lt; ActionController::Rescue (module included)</span>
        <span class="pl-c"># &lt; AbstractController::Callbacks (module included)</span>
        <span class="pl-c"># &lt; ActionController::ImplicitRender (module included)</span>
        <span class="pl-c"># &lt; ActionController::BasicImplicitRender (module included)</span>
        <span class="pl-c"># &lt; ActionController::Renderers (module included) </span>
        <span class="pl-c"># &lt; ActionController::Rendering (module included) </span>
        <span class="pl-c"># &lt; ActionView::Layouts (module included) </span>
        <span class="pl-c"># &lt; ActionView::Rendering (module included)</span>
        <span class="pl-c"># &lt; ActionDispatch::Routing::UrlFor (module included) </span>
        <span class="pl-c"># &lt; AbstractController::Rendering (module included)</span>
        <span class="pl-c"># &lt; ActionController::Metal</span>
        <span class="pl-c"># &lt; AbstractController::Base</span>
        <span class="pl-en">new</span><span class="pl-kos">.</span><span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">request</span><span class="pl-kos">,</span> <span class="pl-s1">response</span><span class="pl-kos">)</span>
      <span class="pl-en">set_request!</span><span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">)</span>
      <span class="pl-en">set_response!</span><span class="pl-kos">(</span><span class="pl-s1">response</span><span class="pl-kos">)</span>
      <span class="pl-en">process</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-en">commit_flash</span>
      <span class="pl-en">to_a</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">to_a</span>
      <span class="pl-en">response</span><span class="pl-kos">.</span><span class="pl-en">to_a</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/abstract_controller/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">AbstractController</span>
  <span class="pl-k">class</span> <span class="pl-v">Base</span>
    <span class="pl-k">def</span> <span class="pl-en">process</span><span class="pl-kos">(</span><span class="pl-s1">action</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-c1">@_action_name</span> <span class="pl-c1">=</span> <span class="pl-s1">action</span><span class="pl-kos">.</span><span class="pl-en">to_s</span>

      <span class="pl-k">unless</span> <span class="pl-s1">action_name</span> <span class="pl-c1">=</span> <span class="pl-en">_find_action_name</span><span class="pl-kos">(</span><span class="pl-c1">@_action_name</span><span class="pl-kos">)</span>
        <span class="pl-en">raise</span> <span class="pl-v">ActionNotFound</span><span class="pl-kos">,</span> <span class="pl-s">"The action '<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-s1">action</span><span class="pl-kos">}</span></span>' could not be found for <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">name</span><span class="pl-kos">}</span></span>"</span>
      <span class="pl-k">end</span>

      <span class="pl-c1">@_response_body</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>

      <span class="pl-c"># action_name: 'index'</span>
      <span class="pl-en">process_action</span><span class="pl-kos">(</span><span class="pl-s1">action_name</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Instrumentation</span>
    <span class="pl-k">def</span> <span class="pl-en">process_action</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-s1">raw_payload</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
        <span class="pl-pds">controller</span>: <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">name</span><span class="pl-kos">,</span>
        <span class="pl-pds">action</span>: <span class="pl-en">action_name</span><span class="pl-kos">,</span>
        <span class="pl-pds">params</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">filtered_parameters</span><span class="pl-kos">,</span>
        <span class="pl-pds">headers</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">headers</span><span class="pl-kos">,</span>
        <span class="pl-pds">format</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">format</span><span class="pl-kos">.</span><span class="pl-en">ref</span><span class="pl-kos">,</span>
        <span class="pl-pds">method</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">request_method</span><span class="pl-kos">,</span>
        <span class="pl-pds">path</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">fullpath</span>
      <span class="pl-kos">}</span>
    
      <span class="pl-v">ActiveSupport</span>::<span class="pl-v">Notifications</span><span class="pl-kos">.</span><span class="pl-en">instrument</span><span class="pl-kos">(</span><span class="pl-s">"start_processing.action_controller"</span><span class="pl-kos">,</span> <span class="pl-s1">raw_payload</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-kos">)</span>
    
      <span class="pl-v">ActiveSupport</span>::<span class="pl-v">Notifications</span><span class="pl-kos">.</span><span class="pl-en">instrument</span><span class="pl-kos">(</span><span class="pl-s">"process_action.action_controller"</span><span class="pl-kos">,</span> <span class="pl-s1">raw_payload</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">payload</span>|
        <span class="pl-k">begin</span>
          <span class="pl-c"># self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;</span>
          <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-smi">super</span> <span class="pl-c"># Let's step into this line.</span>
          <span class="pl-s1">payload</span><span class="pl-kos">[</span><span class="pl-pds">:status</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-en">response</span><span class="pl-kos">.</span><span class="pl-en">status</span>
          <span class="pl-s1">result</span>
        <span class="pl-k">ensure</span>
          <span class="pl-en">append_info_to_payload</span><span class="pl-kos">(</span><span class="pl-s1">payload</span><span class="pl-kos">)</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Rescue</span>
    <span class="pl-k">def</span> <span class="pl-en">process_action</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-smi">super</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">rescue</span> <span class="pl-v">Exception</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">exception</span>
      <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">env</span><span class="pl-kos">[</span><span class="pl-s">"action_dispatch.show_detailed_exceptions"</span><span class="pl-kos">]</span> ||= <span class="pl-en">show_detailed_exceptions?</span>
      <span class="pl-en">rescue_with_handler</span><span class="pl-kos">(</span><span class="pl-en">exception</span><span class="pl-kos">)</span> || <span class="pl-en">raise</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>  
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb</span>
<span class="pl-k">module</span> <span class="pl-v">AbstractController</span>
  <span class="pl-c"># = Abstract Controller Callbacks</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># Abstract Controller provides hooks during the life cycle of a controller action.</span>
  <span class="pl-c"># Callbacks allow you to trigger logic during this cycle. Available callbacks are:</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># * &lt;tt&gt;after_action&lt;/tt&gt;</span>
  <span class="pl-c"># * &lt;tt&gt;before_action&lt;/tt&gt;</span>
  <span class="pl-c"># * &lt;tt&gt;skip_before_action&lt;/tt&gt;</span>
  <span class="pl-c"># * ...</span>
  <span class="pl-k">module</span> <span class="pl-v">Callbacks</span>
    <span class="pl-k">def</span> <span class="pl-en">process_action</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-en">run_callbacks</span><span class="pl-kos">(</span><span class="pl-pds">:process_action</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
        <span class="pl-c"># self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;</span>
        <span class="pl-smi">super</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-k">def</span> <span class="pl-en">process_action</span><span class="pl-kos">(</span>*<span class="pl-kos">)</span>
      <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">formats</span> <span class="pl-c1">=</span> <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">formats</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span>&amp;<span class="pl-pds">:ref</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">compact</span>
      <span class="pl-smi">super</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/abstract_controller/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">AbstractController</span>
  <span class="pl-k">class</span> <span class="pl-v">Base</span>
    <span class="pl-k">def</span> <span class="pl-en">process_action</span><span class="pl-kos">(</span><span class="pl-s1">method_name</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-c"># self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;, method_name: 'index'</span>
      <span class="pl-c"># In the end, method 'send_action' is method 'send' by `alias send_action send` </span>
      <span class="pl-en">send_action</span><span class="pl-kos">(</span><span class="pl-s1">method_name</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>

    <span class="pl-k">alias</span> <span class="pl-en">send_action</span> <span class="pl-en">send</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">BasicImplicitRender</span>
    <span class="pl-k">def</span> <span class="pl-en">send_action</span><span class="pl-kos">(</span><span class="pl-s1">method</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-c"># self: #&lt;HomeController:0x00007fcd3c5dfd48&gt;, method_name: 'index'    </span>
      <span class="pl-c"># Because 'send_action' is an alias of 'send',  </span>
      <span class="pl-c"># self.send('index', *args) will goto HomeController#index.</span>
      <span class="pl-s1">x</span> <span class="pl-c1">=</span> <span class="pl-smi">super</span>
      <span class="pl-c"># performed?: false (for this example)</span>
      <span class="pl-s1">x</span><span class="pl-kos">.</span><span class="pl-en">tap</span> <span class="pl-kos">{</span> <span class="pl-en">default_render</span> <span class="pl-k">unless</span> <span class="pl-en">performed?</span> <span class="pl-kos">}</span> <span class="pl-c"># Let's step into 'default_render' later.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./your_project/app/controllers/home_controller.rb</span>
<span class="pl-k">class</span> <span class="pl-v">HomeController</span> &lt; <span class="pl-v">ApplicationController</span>
  <span class="pl-c"># Will go back to BasicImplicitRender#send_action when method 'index' is done.</span>
  <span class="pl-k">def</span> <span class="pl-en">index</span>
    <span class="pl-c"># Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?</span>
    <span class="pl-c"># I will answer this question later. </span>
    <span class="pl-c1">@users</span> <span class="pl-c1">=</span> <span class="pl-v">User</span><span class="pl-kos">.</span><span class="pl-en">all</span><span class="pl-kos">.</span><span class="pl-en">pluck</span><span class="pl-kos">(</span><span class="pl-pds">:id</span><span class="pl-kos">,</span> <span class="pl-pds">:name</span><span class="pl-kos">)</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./app/views/home/index.html.erb
&lt;div class=&quot;container&quot;&gt;
  &lt;h1 class=&quot;display-4 font-italic&quot;&gt;
    &lt;%= t('home.banner_title') %&gt;
    &lt;%= @users %&gt;
  &lt;/h1&gt;
&lt;/div&gt;"><pre># ./app/views/home/index.html.erb
<span class="pl-kos">&lt;</span><span class="pl-ent">div</span> <span class="pl-c1">class</span>="<span class="pl-s">container</span>"<span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">h1</span> <span class="pl-c1">class</span>="<span class="pl-s">display-4 font-italic</span>"<span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span>%= t('home.banner_title') %<span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span>%= @users %<span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">h1</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">div</span><span class="pl-kos">&gt;</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Render view</h3><a id="user-content-render-view" class="anchor" aria-label="Permalink: Render view" href="#render-view"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">As we see in <code>ActionController::BasicImplicitRender::send_action</code>, the last line is <code>default_render</code>.</p>
<p dir="auto">So after <code>HomeController#index</code> is done, Ruby will execute method <code>default_render</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb 
module ActionController
  # Handles implicit rendering for a controller action that does not
  # explicitly respond with +render+, +respond_to+, +redirect+, or +head+.
  module ImplicitRender
    def default_render(*args)
      # Let's step into template_exists?
      if template_exists?(action_name.to_s, _prefixes, variants: request.variant)
        # Rails has found the default template './app/views/home/index.html.erb', so render it.
        render(*args) # Let's step into this line later
      #...
      else
        logger.info &quot;No template found for #{self.class.name}\##{action_name}, rendering head :no_content&quot; if logger
        super
      end
    end
  end
end

# .gems/actionview-5.2.2/lib/action_view/lookup_context.rb
module ActionView
  class LookupContext
    module ViewPaths
      # Rails checks whether the default template exists.
      def exists?(name, prefixes = [], partial = false, keys = [], **options)
        @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
      end
      alias :template_exists? :exists?
    end
  end  
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb
module ActionController
  module Instrumentation
    def render(*args)
      render_output = nil
      self.view_runtime = cleanup_view_runtime do
        Benchmark.ms {
          # self: #&lt;HomeController:0x00007fa7e9c54278&gt; 
          render_output = super # Let's step into super 
        }
      end
      render_output
    end
  end  
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb
module ActionController
  module Rendering
    # Check for double render errors and set the content_type after rendering.
    def render(*args)
      raise ::AbstractController::DoubleRenderError if response_body
      super # Let's step into super
    end
  end
end

# .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb
module AbstractController
  module Rendering
    # Normalizes arguments, options and then delegates render_to_body and
    # sticks the result in &lt;tt&gt;self.response_body&lt;/tt&gt;.
    def render(*args, &amp;block)
      options = _normalize_render(*args, &amp;block)
      
      rendered_body = render_to_body(options) # Let's step into this line.
      
      if options[:html]
        _set_html_content_type
      else
        _set_rendered_content_type rendered_format
      end
      
      self.response_body = rendered_body
    end
  end
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb
module ActionController
  module Renderers
    def render_to_body(options)
      _render_to_body_with_renderer(options) || super # Let's step into this line and 'super' later.
    end
    
    # For this example, this method return nil in the end.
    def _render_to_body_with_renderer(options)
      # The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`
      # '_renderers' is an instance predicate method. For more information, 
      # see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  
      _renderers.each do |name|
        if options.key?(name)
          _process_options(options)
          method_name = Renderers._render_with_renderer_method_name(name)
          return send(method_name, options.delete(name), options)
        end
      end
      nil
    end
  end  
end

# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb
module ActionController
  module Rendering
    def render_to_body(options = {})
      super || _render_in_priorities(options) || &quot; &quot; # Let's step into 'super'
    end
  end
end"><pre><span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb </span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-c"># Handles implicit rendering for a controller action that does not</span>
  <span class="pl-c"># explicitly respond with +render+, +respond_to+, +redirect+, or +head+.</span>
  <span class="pl-k">module</span> <span class="pl-v">ImplicitRender</span>
    <span class="pl-k">def</span> <span class="pl-en">default_render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-c"># Let's step into template_exists?</span>
      <span class="pl-k">if</span> <span class="pl-en">template_exists?</span><span class="pl-kos">(</span><span class="pl-en">action_name</span><span class="pl-kos">.</span><span class="pl-en">to_s</span><span class="pl-kos">,</span> <span class="pl-en">_prefixes</span><span class="pl-kos">,</span> <span class="pl-pds">variants</span>: <span class="pl-en">request</span><span class="pl-kos">.</span><span class="pl-en">variant</span><span class="pl-kos">)</span>
        <span class="pl-c"># Rails has found the default template './app/views/home/index.html.erb', so render it.</span>
        <span class="pl-en">render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line later</span>
      <span class="pl-c">#...</span>
      <span class="pl-k">else</span>
        <span class="pl-en">logger</span><span class="pl-kos">.</span><span class="pl-en">info</span> <span class="pl-s">"No template found for <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">name</span><span class="pl-kos">}</span></span><span class="pl-cce">\#</span><span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">action_name</span><span class="pl-kos">}</span></span>, rendering head :no_content"</span> <span class="pl-k">if</span> <span class="pl-en">logger</span>
        <span class="pl-smi">super</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/lookup_context.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">class</span> <span class="pl-v">LookupContext</span>
    <span class="pl-k">module</span> <span class="pl-v">ViewPaths</span>
      <span class="pl-c"># Rails checks whether the default template exists.</span>
      <span class="pl-k">def</span> <span class="pl-en">exists?</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">prefixes</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">partial</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span><span class="pl-kos">,</span> <span class="pl-s1">keys</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">,</span> **<span class="pl-s1">options</span><span class="pl-kos">)</span>
        <span class="pl-c1">@view_paths</span><span class="pl-kos">.</span><span class="pl-en">exists?</span><span class="pl-kos">(</span>*<span class="pl-en">args_for_lookup</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">prefixes</span><span class="pl-kos">,</span> <span class="pl-s1">partial</span><span class="pl-kos">,</span> <span class="pl-s1">keys</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
      <span class="pl-k">alias</span> <span class="pl-pds">:template_exists?</span> <span class="pl-pds">:exists?</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>  
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Instrumentation</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-s1">render_output</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>
      <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">view_runtime</span> <span class="pl-c1">=</span> <span class="pl-en">cleanup_view_runtime</span> <span class="pl-k">do</span>
        <span class="pl-v">Benchmark</span><span class="pl-kos">.</span><span class="pl-en">ms</span> <span class="pl-kos">{</span>
          <span class="pl-c"># self: #&lt;HomeController:0x00007fa7e9c54278&gt; </span>
          <span class="pl-s1">render_output</span> <span class="pl-c1">=</span> <span class="pl-smi">super</span> <span class="pl-c"># Let's step into super </span>
        <span class="pl-kos">}</span>
      <span class="pl-k">end</span>
      <span class="pl-s1">render_output</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>  
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-c"># Check for double render errors and set the content_type after rendering.</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">)</span>
      <span class="pl-en">raise</span> ::<span class="pl-v">AbstractController</span>::<span class="pl-v">DoubleRenderError</span> <span class="pl-k">if</span> <span class="pl-en">response_body</span>
      <span class="pl-smi">super</span> <span class="pl-c"># Let's step into super</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb</span>
<span class="pl-k">module</span> <span class="pl-v">AbstractController</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-c"># Normalizes arguments, options and then delegates render_to_body and</span>
    <span class="pl-c"># sticks the result in &lt;tt&gt;self.response_body&lt;/tt&gt;.</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-en">_normalize_render</span><span class="pl-kos">(</span>*<span class="pl-s1">args</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      
      <span class="pl-s1">rendered_body</span> <span class="pl-c1">=</span> <span class="pl-en">render_to_body</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      
      <span class="pl-k">if</span> <span class="pl-s1">options</span><span class="pl-kos">[</span><span class="pl-pds">:html</span><span class="pl-kos">]</span>
        <span class="pl-en">_set_html_content_type</span>
      <span class="pl-k">else</span>
        <span class="pl-en">_set_rendered_content_type</span> <span class="pl-en">rendered_format</span>
      <span class="pl-k">end</span>
      
      <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">response_body</span> <span class="pl-c1">=</span> <span class="pl-s1">rendered_body</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Renderers</span>
    <span class="pl-k">def</span> <span class="pl-en">render_to_body</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-en">_render_to_body_with_renderer</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span> || <span class="pl-smi">super</span> <span class="pl-c"># Let's step into this line and 'super' later.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># For this example, this method return nil in the end.</span>
    <span class="pl-k">def</span> <span class="pl-en">_render_to_body_with_renderer</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-c"># The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`</span>
      <span class="pl-c"># '_renderers' is an instance predicate method. For more information, </span>
      <span class="pl-c"># see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  </span>
      <span class="pl-en">_renderers</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">name</span>|
        <span class="pl-k">if</span> <span class="pl-s1">options</span><span class="pl-kos">.</span><span class="pl-en">key?</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span>
          <span class="pl-en">_process_options</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
          <span class="pl-s1">method_name</span> <span class="pl-c1">=</span> <span class="pl-v">Renderers</span><span class="pl-kos">.</span><span class="pl-en">_render_with_renderer_method_name</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span>
          <span class="pl-k">return</span> <span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-s1">method_name</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">.</span><span class="pl-en">delete</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
      <span class="pl-c1">nil</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>  
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionController</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-k">def</span> <span class="pl-en">render_to_body</span><span class="pl-kos">(</span><span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-smi">super</span> || <span class="pl-en">_render_in_priorities</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span> || <span class="pl-s">" "</span> <span class="pl-c"># Let's step into 'super'</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/actionview-5.2.2/lib/action_view/rendering.rb
module ActionView
  module Rendering
    def render_to_body(options = {})
      _process_options(options)
      
      _render_template(options) # Let's step into this line.
    end
    
    def _render_template(options)
      variant = options.delete(:variant)
      assigns = options.delete(:assigns)
      
      context = view_context # We will step into this line later.
        
      context.assign assigns if assigns
      lookup_context.rendered_format = nil if options[:formats]
      lookup_context.variants = variant if variant
        
      view_renderer.render(context, options) # Let's step into this line.
    end
  end
end

# .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb
module ActionView
  class Renderer
    def render(context, options)
      if options.key?(:partial)
        render_partial(context, options)
      else
        render_template(context, options) # Let's step into this line.
      end
    end
    
    # Direct access to template rendering.
    def render_template(context, options)
      TemplateRenderer.new(@lookup_context).render(context, options) # Let's step into this line.
    end
  end
end

# .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb
module ActionView
  class TemplateRenderer &lt; AbstractRenderer
    def render(context, options)
      @view    = context
      @details = extract_details(options)
      template = determine_template(options)

      prepend_formats(template.formats)

      @lookup_context.rendered_format ||= (template.formats.first || formats.first)

      render_template(template, options[:layout], options[:locals]) # Let's step into this line.
    end
    
    def render_template(template, layout_name = nil, locals = nil)
      view, locals = @view, locals || {}

      render_with_layout(layout_name, locals) do |layout| # Let's step into this line
        instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
          # template: #&lt;ActionView::Template:0x00007f822759cbc0&gt;
          template.render(view, locals) { |*name| view._layout_for(*name) } # Let's step into this line
        end
      end
    end
    
    def render_with_layout(path, locals)
      layout  = path &amp;&amp; find_layout(path, locals.keys, [formats.first])
      content = yield(layout)

      if layout
        view = @view
        view.view_flow.set(:layout, content)
        layout.render(view, locals) { |*name| view._layout_for(*name) }
      else
        content
      end
    end
  end
end

# .gems/actionview-5.2.2/lib/action_view/template.rb
module ActionView
  class Template
    def render(view, locals, buffer = nil, &amp;block)
      instrument_render_template do
        # self: #&lt;ActionView::Template:0x00007f89bab1efb8 
        #           @identifier=&quot;/path/to/your/project/app/views/home/index.html.erb&quot; 
        #           @source=&quot;&lt;div class='container'\n ...&quot;
        #        &gt;
        compile!(view)
        # method_name: &quot;_app_views_home_index_html_erb___3699380246341444633_70336654511160&quot; (This method is defined in 'def compile(mod)' below)
        # view: #&lt;#&lt;Class:0x00007ff10d6c9d18&gt;:0x00007ff10ea050a8&gt;, view is an instance of &lt;a subclass of ActionView::Base&gt; which has same instance variables defined in the instance of HomeController.
        # You will get the result html after invoking 'view.send'. 
        view.send(method_name, locals, buffer, &amp;block)
      end
    rescue =&gt; e
      handle_render_error(view, e)
    end
    
    # Compile a template. This method ensures a template is compiled
    # just once and removes the source after it is compiled.
    def compile!(view)
      return if @compiled

      # Templates can be used concurrently in threaded environments
      # so compilation and any instance variable modification must
      # be synchronized
      @compile_mutex.synchronize do
        # Any thread holding this lock will be compiling the template needed
        # by the threads waiting. So re-check the @compiled flag to avoid
        # re-compilation
        return if @compiled

        if view.is_a?(ActionView::CompiledTemplates)
          mod = ActionView::CompiledTemplates
        else
          mod = view.singleton_class
        end

        instrument(&quot;!compile_template&quot;) do
          compile(mod) # Let's step into this line.
        end

        # Just discard the source if we have a virtual path. This
        # means we can get the template back.
        @source = nil if @virtual_path
        @compiled = true
      end
    end
    
    def compile(mod)
      encode!
      # @handler: #&lt;ActionView::Template::Handlers::ERB:0x00007ff10e1be188&gt;
      code = @handler.call(self) # Let's step into this line.

      # Make sure that the resulting String to be eval'd is in the
      # encoding of the code
      source = &lt;&lt;-end_src.dup
        def #{method_name}(local_assigns, output_buffer)
          _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
        ensure
          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
        end
      end_src

      # ...

      #  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)
      #              _old_virtual_path, @virtual_path = @virtual_path, &quot;home/index&quot;;_old_output_buffer = @output_buffer;;
      #              @output_buffer = output_buffer || ActionView::OutputBuffer.new;
      #              @output_buffer.safe_append='&lt;div class=&quot;container&quot;&gt;
      #                &lt;h1 class=&quot;display-4 font-italic&quot;&gt;
      #                  '.freeze;
      #                   @output_buffer.append=( t('home.banner_title') );
      #                   @output_buffer.append=( @users ); 
      #                   @output_buffer.safe_append='
      #                &lt;/h1&gt;
      #              &lt;/div&gt;
      #              '.freeze;
      #              @output_buffer.to_s
      #            ensure
      #              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
      #            end
      mod.module_eval(source, identifier, 0) # This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'
      # mod: ActionView::CompiledTemplates
      ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
    end

# .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     
    module Handlers
      class ERB
        def call(template)
          template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)

          erb = template_source.gsub(ENCODING_TAG, &quot;&quot;)
          encoding = $2

          erb.force_encoding valid_encoding(template.source.dup, encoding)

          # Always make sure we return a String in the default_internal
          erb.encode!

          self.class.erb_implementation.new(
            erb,
            escape: (self.class.escape_whitelist.include? template.type),
            trim: (self.class.erb_trim_mode == &quot;-&quot;)
          ).src
        end
      end
    end
  end
end"><pre><span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/rendering.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-k">def</span> <span class="pl-en">render_to_body</span><span class="pl-kos">(</span><span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-en">_process_options</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
      
      <span class="pl-en">_render_template</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">_render_template</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-s1">variant</span> <span class="pl-c1">=</span> <span class="pl-s1">options</span><span class="pl-kos">.</span><span class="pl-en">delete</span><span class="pl-kos">(</span><span class="pl-pds">:variant</span><span class="pl-kos">)</span>
      <span class="pl-s1">assigns</span> <span class="pl-c1">=</span> <span class="pl-s1">options</span><span class="pl-kos">.</span><span class="pl-en">delete</span><span class="pl-kos">(</span><span class="pl-pds">:assigns</span><span class="pl-kos">)</span>
      
      <span class="pl-s1">context</span> <span class="pl-c1">=</span> <span class="pl-en">view_context</span> <span class="pl-c"># We will step into this line later.</span>
        
      <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">assign</span> <span class="pl-s1">assigns</span> <span class="pl-k">if</span> <span class="pl-s1">assigns</span>
      <span class="pl-en">lookup_context</span><span class="pl-kos">.</span><span class="pl-en">rendered_format</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span> <span class="pl-k">if</span> <span class="pl-s1">options</span><span class="pl-kos">[</span><span class="pl-pds">:formats</span><span class="pl-kos">]</span>
      <span class="pl-en">lookup_context</span><span class="pl-kos">.</span><span class="pl-en">variants</span> <span class="pl-c1">=</span> <span class="pl-s1">variant</span> <span class="pl-k">if</span> <span class="pl-s1">variant</span>
        
      <span class="pl-en">view_renderer</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">class</span> <span class="pl-v">Renderer</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-k">if</span> <span class="pl-s1">options</span><span class="pl-kos">.</span><span class="pl-en">key?</span><span class="pl-kos">(</span><span class="pl-pds">:partial</span><span class="pl-kos">)</span>
        <span class="pl-en">render_partial</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-k">else</span>
        <span class="pl-en">render_template</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Direct access to template rendering.</span>
    <span class="pl-k">def</span> <span class="pl-en">render_template</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-v">TemplateRenderer</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@lookup_context</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">class</span> <span class="pl-v">TemplateRenderer</span> &lt; <span class="pl-v">AbstractRenderer</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-c1">@view</span>    <span class="pl-c1">=</span> <span class="pl-s1">context</span>
      <span class="pl-c1">@details</span> <span class="pl-c1">=</span> <span class="pl-en">extract_details</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>
      <span class="pl-s1">template</span> <span class="pl-c1">=</span> <span class="pl-en">determine_template</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span>

      <span class="pl-en">prepend_formats</span><span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">formats</span><span class="pl-kos">)</span>

      <span class="pl-c1">@lookup_context</span><span class="pl-kos">.</span><span class="pl-en">rendered_format</span> ||= <span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">formats</span><span class="pl-kos">.</span><span class="pl-en">first</span> || <span class="pl-en">formats</span><span class="pl-kos">.</span><span class="pl-en">first</span><span class="pl-kos">)</span>

      <span class="pl-en">render_template</span><span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">[</span><span class="pl-pds">:layout</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">[</span><span class="pl-pds">:locals</span><span class="pl-kos">]</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">render_template</span><span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">,</span> <span class="pl-s1">layout_name</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">)</span>
      <span class="pl-s1">view</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span> <span class="pl-c1">=</span> <span class="pl-c1">@view</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span> || <span class="pl-kos">{</span><span class="pl-kos">}</span>

      <span class="pl-en">render_with_layout</span><span class="pl-kos">(</span><span class="pl-s1">layout_name</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">layout</span>| <span class="pl-c"># Let's step into this line</span>
        <span class="pl-en">instrument</span><span class="pl-kos">(</span><span class="pl-pds">:template</span><span class="pl-kos">,</span> <span class="pl-pds">identifier</span>: <span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">identifier</span><span class="pl-kos">,</span> <span class="pl-pds">layout</span>: <span class="pl-s1">layout</span><span class="pl-kos">.</span><span class="pl-en">try</span><span class="pl-kos">(</span><span class="pl-pds">:virtual_path</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
          <span class="pl-c"># template: #&lt;ActionView::Template:0x00007f822759cbc0&gt;</span>
          <span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> |*<span class="pl-s1">name</span>| <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">_layout_for</span><span class="pl-kos">(</span>*<span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-kos">}</span> <span class="pl-c"># Let's step into this line</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">render_with_layout</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">)</span>
      <span class="pl-s1">layout</span>  <span class="pl-c1">=</span> <span class="pl-s1">path</span> &amp;&amp; <span class="pl-en">find_layout</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-en">formats</span><span class="pl-kos">.</span><span class="pl-en">first</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
      <span class="pl-s1">content</span> <span class="pl-c1">=</span> <span class="pl-k">yield</span><span class="pl-kos">(</span><span class="pl-s1">layout</span><span class="pl-kos">)</span>

      <span class="pl-k">if</span> <span class="pl-s1">layout</span>
        <span class="pl-s1">view</span> <span class="pl-c1">=</span> <span class="pl-c1">@view</span>
        <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">view_flow</span><span class="pl-kos">.</span><span class="pl-en">set</span><span class="pl-kos">(</span><span class="pl-pds">:layout</span><span class="pl-kos">,</span> <span class="pl-s1">content</span><span class="pl-kos">)</span>
        <span class="pl-s1">layout</span><span class="pl-kos">.</span><span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> |*<span class="pl-s1">name</span>| <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">_layout_for</span><span class="pl-kos">(</span>*<span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-kos">}</span>
      <span class="pl-k">else</span>
        <span class="pl-s1">content</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/template.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">class</span> <span class="pl-v">Template</span>
    <span class="pl-k">def</span> <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-en">instrument_render_template</span> <span class="pl-k">do</span>
        <span class="pl-c"># self: #&lt;ActionView::Template:0x00007f89bab1efb8 </span>
        <span class="pl-c">#           @identifier="/path/to/your/project/app/views/home/index.html.erb" </span>
        <span class="pl-c">#           @source="&lt;div class='container'\n ..."</span>
        <span class="pl-c">#        &gt;</span>
        <span class="pl-en">compile!</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">)</span>
        <span class="pl-c"># method_name: "_app_views_home_index_html_erb___3699380246341444633_70336654511160" (This method is defined in 'def compile(mod)' below)</span>
        <span class="pl-c"># view: #&lt;#&lt;Class:0x00007ff10d6c9d18&gt;:0x00007ff10ea050a8&gt;, view is an instance of &lt;a subclass of ActionView::Base&gt; which has same instance variables defined in the instance of HomeController.</span>
        <span class="pl-c"># You will get the result html after invoking 'view.send'. </span>
        <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span><span class="pl-en">method_name</span><span class="pl-kos">,</span> <span class="pl-s1">locals</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
    <span class="pl-k">rescue</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">e</span>
      <span class="pl-en">handle_render_error</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">,</span> <span class="pl-en">e</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Compile a template. This method ensures a template is compiled</span>
    <span class="pl-c"># just once and removes the source after it is compiled.</span>
    <span class="pl-k">def</span> <span class="pl-en">compile!</span><span class="pl-kos">(</span><span class="pl-s1">view</span><span class="pl-kos">)</span>
      <span class="pl-k">return</span> <span class="pl-k">if</span> <span class="pl-c1">@compiled</span>

      <span class="pl-c"># Templates can be used concurrently in threaded environments</span>
      <span class="pl-c"># so compilation and any instance variable modification must</span>
      <span class="pl-c"># be synchronized</span>
      <span class="pl-c1">@compile_mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-c"># Any thread holding this lock will be compiling the template needed</span>
        <span class="pl-c"># by the threads waiting. So re-check the @compiled flag to avoid</span>
        <span class="pl-c"># re-compilation</span>
        <span class="pl-k">return</span> <span class="pl-k">if</span> <span class="pl-c1">@compiled</span>

        <span class="pl-k">if</span> <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">is_a?</span><span class="pl-kos">(</span><span class="pl-v">ActionView</span>::<span class="pl-v">CompiledTemplates</span><span class="pl-kos">)</span>
          <span class="pl-s1">mod</span> <span class="pl-c1">=</span> <span class="pl-v">ActionView</span>::<span class="pl-v">CompiledTemplates</span>
        <span class="pl-k">else</span>
          <span class="pl-s1">mod</span> <span class="pl-c1">=</span> <span class="pl-s1">view</span><span class="pl-kos">.</span><span class="pl-en">singleton_class</span>
        <span class="pl-k">end</span>

        <span class="pl-en">instrument</span><span class="pl-kos">(</span><span class="pl-s">"!compile_template"</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
          <span class="pl-en">compile</span><span class="pl-kos">(</span><span class="pl-s1">mod</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-k">end</span>

        <span class="pl-c"># Just discard the source if we have a virtual path. This</span>
        <span class="pl-c"># means we can get the template back.</span>
        <span class="pl-c1">@source</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span> <span class="pl-k">if</span> <span class="pl-c1">@virtual_path</span>
        <span class="pl-c1">@compiled</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">compile</span><span class="pl-kos">(</span><span class="pl-s1">mod</span><span class="pl-kos">)</span>
      <span class="pl-en">encode!</span>
      <span class="pl-c"># @handler: #&lt;ActionView::Template::Handlers::ERB:0x00007ff10e1be188&gt;</span>
      <span class="pl-s1">code</span> <span class="pl-c1">=</span> <span class="pl-c1">@handler</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>

      <span class="pl-c"># Make sure that the resulting String to be eval'd is in the</span>
      <span class="pl-c"># encoding of the code</span>
      <span class="pl-s1">source</span> <span class="pl-c1">=</span> <span class="pl-s">&lt;&lt;-end_src</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-s"></span>
<span class="pl-s">        def <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">method_name</span><span class="pl-kos">}</span></span>(local_assigns, output_buffer)</span>
<span class="pl-s">          _old_virtual_path, @virtual_path = @virtual_path, <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-c1">@virtual_path</span><span class="pl-kos">.</span><span class="pl-en">inspect</span><span class="pl-kos">}</span></span>;_old_output_buffer = @output_buffer;<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">locals_code</span><span class="pl-kos">}</span></span>;<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-s1">code</span><span class="pl-kos">}</span></span></span>
<span class="pl-s">        ensure</span>
<span class="pl-s">          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer</span>
<span class="pl-s">        end</span>
<span class="pl-s">      end_src</span>

      <span class="pl-c"># ...</span>

      <span class="pl-c">#  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)</span>
      <span class="pl-c">#              _old_virtual_path, @virtual_path = @virtual_path, "home/index";_old_output_buffer = @output_buffer;;</span>
      <span class="pl-c">#              @output_buffer = output_buffer || ActionView::OutputBuffer.new;</span>
      <span class="pl-c">#              @output_buffer.safe_append='&lt;div class="container"&gt;</span>
      <span class="pl-c">#                &lt;h1 class="display-4 font-italic"&gt;</span>
      <span class="pl-c">#                  '.freeze;</span>
      <span class="pl-c">#                   @output_buffer.append=( t('home.banner_title') );</span>
      <span class="pl-c">#                   @output_buffer.append=( @users ); </span>
      <span class="pl-c">#                   @output_buffer.safe_append='</span>
      <span class="pl-c">#                &lt;/h1&gt;</span>
      <span class="pl-c">#              &lt;/div&gt;</span>
      <span class="pl-c">#              '.freeze;</span>
      <span class="pl-c">#              @output_buffer.to_s</span>
      <span class="pl-c">#            ensure</span>
      <span class="pl-c">#              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer</span>
      <span class="pl-c">#            end</span>
      <span class="pl-s1">mod</span><span class="pl-kos">.</span><span class="pl-en">module_eval</span><span class="pl-kos">(</span><span class="pl-s1">source</span><span class="pl-kos">,</span> <span class="pl-en">identifier</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">)</span> <span class="pl-c"># This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'</span>
      <span class="pl-c"># mod: ActionView::CompiledTemplates</span>
      <span class="pl-v">ObjectSpace</span><span class="pl-kos">.</span><span class="pl-en">define_finalizer</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-v">Finalizer</span><span class="pl-kos">[</span><span class="pl-en">method_name</span><span class="pl-kos">,</span> <span class="pl-s1">mod</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>

<span class="pl-c"># .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     </span>
    <span class="pl-k">module</span> <span class="pl-v">Handlers</span>
      <span class="pl-k">class</span> <span class="pl-c1">ERB</span>
        <span class="pl-k">def</span> <span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">)</span>
          <span class="pl-s1">template_source</span> <span class="pl-c1">=</span> <span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">source</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-kos">.</span><span class="pl-en">force_encoding</span><span class="pl-kos">(</span><span class="pl-v">Encoding</span>::<span class="pl-c1">ASCII_8BIT</span><span class="pl-kos">)</span>

          <span class="pl-s1">erb</span> <span class="pl-c1">=</span> <span class="pl-s1">template_source</span><span class="pl-kos">.</span><span class="pl-en">gsub</span><span class="pl-kos">(</span><span class="pl-c1">ENCODING_TAG</span><span class="pl-kos">,</span> <span class="pl-s">""</span><span class="pl-kos">)</span>
          <span class="pl-s1">encoding</span> <span class="pl-c1">=</span> $2

          <span class="pl-s1">erb</span><span class="pl-kos">.</span><span class="pl-en">force_encoding</span> <span class="pl-en">valid_encoding</span><span class="pl-kos">(</span><span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">source</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-kos">,</span> <span class="pl-s1">encoding</span><span class="pl-kos">)</span>

          <span class="pl-c"># Always make sure we return a String in the default_internal</span>
          <span class="pl-s1">erb</span><span class="pl-kos">.</span><span class="pl-en">encode!</span>

          <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">erb_implementation</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span>
            <span class="pl-s1">erb</span><span class="pl-kos">,</span>
            <span class="pl-pds">escape</span>: <span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">escape_whitelist</span><span class="pl-kos">.</span><span class="pl-en">include?</span> <span class="pl-s1">template</span><span class="pl-kos">.</span><span class="pl-en">type</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
            <span class="pl-pds">trim</span>: <span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">erb_trim_mode</span> == <span class="pl-s">"-"</span><span class="pl-kos">)</span>
          <span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">src</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">How can instance variables defined in Controller be accessed in view file?</h3><a id="user-content-how-can-instance-variables-defined-in-controller-be-accessed-in-view-file" class="anchor" aria-label="Permalink: How can instance variables defined in Controller be accessed in view file?" href="#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">It's time to answer the question before:</p>
<p dir="auto">How can instance variables like <code>@users</code> defined in <code>HomeController</code> be accessed in <code>./app/views/home/index.html.erb</code>?</p>
<p dir="auto">I will answer this question by showing the source code below.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/actionview-5.2.2/lib/action_view/rendering.rb
module ActionView
  module Rendering
    def view_context
      # view_context_class is a subclass of ActionView::Base.
      view_context_class.new( # Let's step into this line later.
        view_renderer,
        view_assigns, # This line will set the instance variables like '@users' in this example. Let's step into this line.  
        self
      )
    end
    
    def view_assigns
      # self: #&lt;HomeController:0x00007f83ecfed310&gt;
      protected_vars = _protected_ivars
      # instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  
      variables      = instance_variables 

      variables.reject! { |s| protected_vars.include? s }
      ret = variables.each_with_object({}) { |name, hash|
        hash[name.slice(1, name.length)] = instance_variable_get(name)
      }
      
      # ret: {&quot;marked_for_same_origin_verification&quot;=&gt;true, &quot;users&quot;=&gt;[[1, &quot;Lane&quot;], [2, &quot;John&quot;], [4, &quot;Frank&quot;]]}
      ret
    end
    
    def view_context_class
      # Will return a subclass of ActionView::Base.
      @_view_context_class ||= self.class.view_context_class
    end
    
    # How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb
    # FYI, the method 'append_features' will be executed automatically before method 'included' executed. 
    # https://apidock.com/ruby/v1_9_3_392/Module/append_features  
    module ClassMethods
      def view_context_class
        # self: HomeController
        @view_context_class ||= begin
          supports_path = supports_path?
          routes  = respond_to?(:_routes)  &amp;&amp; _routes
          helpers = respond_to?(:_helpers) &amp;&amp; _helpers

          Class.new(ActionView::Base) do
            if routes
              include routes.url_helpers(supports_path)
              include routes.mounted_helpers
            end

            if helpers
              include helpers
            end
          end
        end
      end
    end
  end
end

# ./gems/actionview-5.2.2/lib/action_view/base.rb
module ActionView
  class Base
    def initialize(context = nil, assigns = {}, controller = nil, formats = nil)
      @_config = ActiveSupport::InheritableOptions.new

      if context.is_a?(ActionView::Renderer)
        @view_renderer = context
      else
        lookup_context = context.is_a?(ActionView::LookupContext) ?
          context : ActionView::LookupContext.new(context)
        lookup_context.formats  = formats if formats
        lookup_context.prefixes = controller._prefixes if controller
        @view_renderer = ActionView::Renderer.new(lookup_context)
      end

      @cache_hit = {}
      
      assign(assigns) # Let's step into this line.
      
      assign_controller(controller)
      _prepare_context
    end
    
    def assign(new_assigns)
      @_assigns = 
        new_assigns.each do |key, value|
          # This line will set the instance variables (like '@users') in HomeController to itself.
          instance_variable_set(&quot;@#{key}&quot;, value)
        end
    end
  end
end
"><pre><span class="pl-c"># ./gems/actionview-5.2.2/lib/action_view/rendering.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">module</span> <span class="pl-v">Rendering</span>
    <span class="pl-k">def</span> <span class="pl-en">view_context</span>
      <span class="pl-c"># view_context_class is a subclass of ActionView::Base.</span>
      <span class="pl-en">view_context_class</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span> <span class="pl-c"># Let's step into this line later.</span>
        <span class="pl-en">view_renderer</span><span class="pl-kos">,</span>
        <span class="pl-en">view_assigns</span><span class="pl-kos">,</span> <span class="pl-c"># This line will set the instance variables like '@users' in this example. Let's step into this line.  </span>
        <span class="pl-smi">self</span>
      <span class="pl-kos">)</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">view_assigns</span>
      <span class="pl-c"># self: #&lt;HomeController:0x00007f83ecfed310&gt;</span>
      <span class="pl-s1">protected_vars</span> <span class="pl-c1">=</span> <span class="pl-en">_protected_ivars</span>
      <span class="pl-c"># instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  </span>
      <span class="pl-s1">variables</span>      <span class="pl-c1">=</span> <span class="pl-en">instance_variables</span> 

      <span class="pl-s1">variables</span><span class="pl-kos">.</span><span class="pl-en">reject!</span> <span class="pl-kos">{</span> |<span class="pl-s1">s</span>| <span class="pl-s1">protected_vars</span><span class="pl-kos">.</span><span class="pl-en">include?</span> <span class="pl-s1">s</span> <span class="pl-kos">}</span>
      <span class="pl-s1">ret</span> <span class="pl-c1">=</span> <span class="pl-s1">variables</span><span class="pl-kos">.</span><span class="pl-en">each_with_object</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> |<span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">hash</span>|
        <span class="pl-s1">hash</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">.</span><span class="pl-en">slice</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-s1">name</span><span class="pl-kos">.</span><span class="pl-en">length</span><span class="pl-kos">)</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-en">instance_variable_get</span><span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span>
      <span class="pl-kos">}</span>
      
      <span class="pl-c"># ret: {"marked_for_same_origin_verification"=&gt;true, "users"=&gt;[[1, "Lane"], [2, "John"], [4, "Frank"]]}</span>
      <span class="pl-s1">ret</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">view_context_class</span>
      <span class="pl-c"># Will return a subclass of ActionView::Base.</span>
      <span class="pl-c1">@_view_context_class</span> ||= <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">.</span><span class="pl-en">view_context_class</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb</span>
    <span class="pl-c"># FYI, the method 'append_features' will be executed automatically before method 'included' executed. </span>
    <span class="pl-c"># https://apidock.com/ruby/v1_9_3_392/Module/append_features  </span>
    <span class="pl-k">module</span> <span class="pl-v">ClassMethods</span>
      <span class="pl-k">def</span> <span class="pl-en">view_context_class</span>
        <span class="pl-c"># self: HomeController</span>
        <span class="pl-c1">@view_context_class</span> ||= <span class="pl-k">begin</span>
          <span class="pl-s1">supports_path</span> <span class="pl-c1">=</span> <span class="pl-en">supports_path?</span>
          <span class="pl-s1">routes</span>  <span class="pl-c1">=</span> <span class="pl-en">respond_to?</span><span class="pl-kos">(</span><span class="pl-pds">:_routes</span><span class="pl-kos">)</span>  &amp;&amp; <span class="pl-en">_routes</span>
          <span class="pl-s1">helpers</span> <span class="pl-c1">=</span> <span class="pl-en">respond_to?</span><span class="pl-kos">(</span><span class="pl-pds">:_helpers</span><span class="pl-kos">)</span> &amp;&amp; <span class="pl-en">_helpers</span>

          <span class="pl-v">Class</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-v">ActionView</span>::<span class="pl-v">Base</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
            <span class="pl-k">if</span> <span class="pl-s1">routes</span>
              <span class="pl-en">include</span> <span class="pl-s1">routes</span><span class="pl-kos">.</span><span class="pl-en">url_helpers</span><span class="pl-kos">(</span><span class="pl-s1">supports_path</span><span class="pl-kos">)</span>
              <span class="pl-en">include</span> <span class="pl-s1">routes</span><span class="pl-kos">.</span><span class="pl-en">mounted_helpers</span>
            <span class="pl-k">end</span>

            <span class="pl-k">if</span> <span class="pl-s1">helpers</span>
              <span class="pl-en">include</span> <span class="pl-s1">helpers</span>
            <span class="pl-k">end</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/actionview-5.2.2/lib/action_view/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">ActionView</span>
  <span class="pl-k">class</span> <span class="pl-v">Base</span>
    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">context</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">,</span> <span class="pl-s1">assigns</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">controller</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">,</span> <span class="pl-s1">formats</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span><span class="pl-kos">)</span>
      <span class="pl-c1">@_config</span> <span class="pl-c1">=</span> <span class="pl-v">ActiveSupport</span>::<span class="pl-v">InheritableOptions</span><span class="pl-kos">.</span><span class="pl-en">new</span>

      <span class="pl-k">if</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">is_a?</span><span class="pl-kos">(</span><span class="pl-v">ActionView</span>::<span class="pl-v">Renderer</span><span class="pl-kos">)</span>
        <span class="pl-c1">@view_renderer</span> <span class="pl-c1">=</span> <span class="pl-s1">context</span>
      <span class="pl-k">else</span>
        <span class="pl-s1">lookup_context</span> <span class="pl-c1">=</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">is_a?</span><span class="pl-kos">(</span><span class="pl-v">ActionView</span>::<span class="pl-v">LookupContext</span><span class="pl-kos">)</span> ?
          <span class="pl-s1">context</span> : <span class="pl-v">ActionView</span>::<span class="pl-v">LookupContext</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">context</span><span class="pl-kos">)</span>
        <span class="pl-s1">lookup_context</span><span class="pl-kos">.</span><span class="pl-s1">formats</span>  <span class="pl-c1">=</span> <span class="pl-s1">formats</span> <span class="pl-k">if</span> <span class="pl-s1">formats</span>
        <span class="pl-s1">lookup_context</span><span class="pl-kos">.</span><span class="pl-en">prefixes</span> <span class="pl-c1">=</span> <span class="pl-s1">controller</span><span class="pl-kos">.</span><span class="pl-en">_prefixes</span> <span class="pl-k">if</span> <span class="pl-s1">controller</span>
        <span class="pl-c1">@view_renderer</span> <span class="pl-c1">=</span> <span class="pl-v">ActionView</span>::<span class="pl-v">Renderer</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">lookup_context</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>

      <span class="pl-c1">@cache_hit</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
      
      <span class="pl-en">assign</span><span class="pl-kos">(</span><span class="pl-s1">assigns</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      
      <span class="pl-en">assign_controller</span><span class="pl-kos">(</span><span class="pl-s1">controller</span><span class="pl-kos">)</span>
      <span class="pl-en">_prepare_context</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">assign</span><span class="pl-kos">(</span><span class="pl-s1">new_assigns</span><span class="pl-kos">)</span>
      <span class="pl-c1">@_assigns</span> <span class="pl-c1">=</span> 
        <span class="pl-s1">new_assigns</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">key</span><span class="pl-kos">,</span> <span class="pl-s1">value</span>|
          <span class="pl-c"># This line will set the instance variables (like '@users') in HomeController to itself.</span>
          <span class="pl-en">instance_variable_set</span><span class="pl-kos">(</span><span class="pl-s">"@<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-s1">key</span><span class="pl-kos">}</span></span>"</span><span class="pl-kos">,</span> <span class="pl-s1">value</span><span class="pl-kos">)</span>
        <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">After all Rack apps called, user will get the response.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Part 4: What does <code>$ rails server</code> do?</h2><a id="user-content-part-4-what-does--rails-server-do" class="anchor" aria-label="Permalink: Part 4: What does $ rails server do?" href="#part-4-what-does--rails-server-do"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you start Rails by <code>$ rails server</code>. You may want to know what does this command do?</p>
<p dir="auto">The command <code>rails</code> locates at <code>./bin/</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)

require_relative '../config/boot'
require 'rails/commands' # Let's look at this file."><pre><span class="pl-c">#!/usr/bin/env ruby</span>
<span class="pl-c1">APP_PATH</span> <span class="pl-c1">=</span> <span class="pl-v">File</span><span class="pl-kos">.</span><span class="pl-en">expand_path</span><span class="pl-kos">(</span><span class="pl-s">'../config/application'</span><span class="pl-kos">,</span> <span class="pl-en">__dir__</span><span class="pl-kos">)</span>

<span class="pl-en">require_relative</span> <span class="pl-s">'../config/boot'</span>
<span class="pl-en">require</span> <span class="pl-s">'rails/commands'</span> <span class="pl-c"># Let's look at this file.</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./railties-5.2.2/lib/rails/commands.rb
require &quot;rails/command&quot;

aliases = {
  &quot;g&quot;  =&gt; &quot;generate&quot;,
  &quot;d&quot;  =&gt; &quot;destroy&quot;,
  &quot;c&quot;  =&gt; &quot;console&quot;,
  &quot;s&quot;  =&gt; &quot;server&quot;,
  &quot;db&quot; =&gt; &quot;dbconsole&quot;,
  &quot;r&quot;  =&gt; &quot;runner&quot;,
  &quot;t&quot;  =&gt; &quot;test&quot;
}

command = ARGV.shift
command = aliases[command] || command # command is 'server'

Rails::Command.invoke command, ARGV # Let's step into this line."><pre><span class="pl-c"># ./railties-5.2.2/lib/rails/commands.rb</span>
<span class="pl-en">require</span> <span class="pl-s">"rails/command"</span>

<span class="pl-s1">aliases</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  <span class="pl-s">"g"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"generate"</span><span class="pl-kos">,</span>
  <span class="pl-s">"d"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"destroy"</span><span class="pl-kos">,</span>
  <span class="pl-s">"c"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"console"</span><span class="pl-kos">,</span>
  <span class="pl-s">"s"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"server"</span><span class="pl-kos">,</span>
  <span class="pl-s">"db"</span> <span class="pl-c1">=&gt;</span> <span class="pl-s">"dbconsole"</span><span class="pl-kos">,</span>
  <span class="pl-s">"r"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"runner"</span><span class="pl-kos">,</span>
  <span class="pl-s">"t"</span>  <span class="pl-c1">=&gt;</span> <span class="pl-s">"test"</span>
<span class="pl-kos">}</span>

<span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-c1">ARGV</span><span class="pl-kos">.</span><span class="pl-en">shift</span>
<span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-s1">aliases</span><span class="pl-kos">[</span><span class="pl-s1">command</span><span class="pl-kos">]</span> || <span class="pl-s1">command</span> <span class="pl-c"># command is 'server'</span>

<span class="pl-v">Rails</span>::<span class="pl-v">Command</span><span class="pl-kos">.</span><span class="pl-en">invoke</span> <span class="pl-s1">command</span><span class="pl-kos">,</span> <span class="pl-c1">ARGV</span> <span class="pl-c"># Let's step into this line.</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./railties-5.2.2/lib/rails/command.rb
module Rails
  module Command
    class &lt;&lt; self
      def invoke(full_namespace, args = [], **config)
        # ...
        # command_name: 'server'  
        # After calling `find_by_namespace`, we will get this result:
        # command: Rails::Command::ServerCommand
        command = find_by_namespace(namespace, command_name)
        
        # Equals to: Rails::Command::ServerCommand.perform('server', args, config)
        command.perform(command_name, args, config)
      end
    end
  end
end"><pre><span class="pl-c"># ./railties-5.2.2/lib/rails/command.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
      <span class="pl-k">def</span> <span class="pl-en">invoke</span><span class="pl-kos">(</span><span class="pl-s1">full_namespace</span><span class="pl-kos">,</span> <span class="pl-s1">args</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">,</span> **<span class="pl-s1">config</span><span class="pl-kos">)</span>
        <span class="pl-c"># ...</span>
        <span class="pl-c"># command_name: 'server'  </span>
        <span class="pl-c"># After calling `find_by_namespace`, we will get this result:</span>
        <span class="pl-c"># command: Rails::Command::ServerCommand</span>
        <span class="pl-s1">command</span> <span class="pl-c1">=</span> <span class="pl-en">find_by_namespace</span><span class="pl-kos">(</span><span class="pl-en">namespace</span><span class="pl-kos">,</span> <span class="pl-en">command_name</span><span class="pl-kos">)</span>
        
        <span class="pl-c"># Equals to: Rails::Command::ServerCommand.perform('server', args, config)</span>
        <span class="pl-s1">command</span><span class="pl-kos">.</span><span class="pl-en">perform</span><span class="pl-kos">(</span><span class="pl-en">command_name</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb
module Rails 
  module Command
    # There is a class method 'perform' in the Base class.
    class ServerCommand &lt; Base
    end
  end
end"><pre><span class="pl-c"># ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span> 
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-c"># There is a class method 'perform' in the Base class.</span>
    <span class="pl-k">class</span> <span class="pl-v">ServerCommand</span> &lt; <span class="pl-v">Base</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Thor</h3><a id="user-content-thor" class="anchor" aria-label="Permalink: Thor" href="#thor"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Thor is a toolkit for building powerful command-line interfaces.</p>
<p dir="auto"><a href="https://github.com/erikhuda/thor">https://github.com/erikhuda/thor</a></p>
<p dir="auto">Inheritance relationship: <code>Rails::Command::ServerCommand &lt; Rails::Command::Base &lt; Thor</code></p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties-5.2.2/lib/rails/command/base.rb
module Rails
  module Command
    class Base &lt; Thor
      class &lt;&lt; self
        # command: 'server'
        def perform(command, args, config)
          #...
          dispatch(command, args.dup, nil, config) # Thor.dispatch
        end
      end
    end
  end
end"><pre><span class="pl-c"># ./gems/railties-5.2.2/lib/rails/command/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-k">class</span> <span class="pl-v">Base</span> &lt; <span class="pl-v">Thor</span>
      <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
        <span class="pl-c"># command: 'server'</span>
        <span class="pl-k">def</span> <span class="pl-en">perform</span><span class="pl-kos">(</span><span class="pl-s1">command</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span>
          <span class="pl-c">#...</span>
          <span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">command</span><span class="pl-kos">,</span> <span class="pl-s1">args</span><span class="pl-kos">.</span><span class="pl-en">dup</span><span class="pl-kos">,</span> <span class="pl-c1">nil</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span> <span class="pl-c"># Thor.dispatch</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/thor-0.20.3/lib/thor.rb
class Thor
  class &lt;&lt; self
    # meth is 'server'
    def dispatch(meth, given_args, given_opts, config)
      # ...
      # Will new a Rails::Command::ServerCommand instance here 
      # because 'self' is Rails::Command::ServerCommand.
      instance = new(args, opts, config)
      # ...
      # Method 'invoke_command' is defined in Thor::Invocation. 
      # command: {Thor::Command}#&lt;struct Thor::Command name=&quot;server&quot; ...&gt; 
      instance.invoke_command(command, trailing || [])
    end
  end
end

# ./gems/thor-0.20.3/lib/thor/invocation.rb
class Thor
  # FYI, this module is included in Thor.
  # And Thor is grandfather of Rails::Command::ServerCommand
  module Invocation
    def invoke_command(command, *args) # 'invoke_command' is defined at here.
      # ...
      # self: #&lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&gt; 
      # command: {Thor::Command}#&lt;struct Thor::Command name=&quot;server&quot; ...&gt; 
      command.run(self, *args)
    end
  end
end

# ./gems/thor-0.20.3/lib/thor/command.rb
class Thor
  class Command &lt; Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
    def run(instance, args = [])
      # ...
      # instance: #&lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&gt;
      # name: &quot;server&quot;
      # This line will invoke Rails::Command::ServerCommand#server, 
      # the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.
      # I will show you how the instance method 'server' is implicitly defined. 
      instance.__send__(name, *args) 
    end  
  end
end"><pre><span class="pl-c"># ./gems/thor-0.20.3/lib/thor.rb</span>
<span class="pl-k">class</span> <span class="pl-v">Thor</span>
  <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
    <span class="pl-c"># meth is 'server'</span>
    <span class="pl-k">def</span> <span class="pl-en">dispatch</span><span class="pl-kos">(</span><span class="pl-s1">meth</span><span class="pl-kos">,</span> <span class="pl-s1">given_args</span><span class="pl-kos">,</span> <span class="pl-s1">given_opts</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c"># Will new a Rails::Command::ServerCommand instance here </span>
      <span class="pl-c"># because 'self' is Rails::Command::ServerCommand.</span>
      <span class="pl-s1">instance</span> <span class="pl-c1">=</span> <span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-en">args</span><span class="pl-kos">,</span> <span class="pl-en">opts</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c"># Method 'invoke_command' is defined in Thor::Invocation. </span>
      <span class="pl-c"># command: {Thor::Command}#&lt;struct Thor::Command name="server" ...&gt; </span>
      <span class="pl-s1">instance</span><span class="pl-kos">.</span><span class="pl-en">invoke_command</span><span class="pl-kos">(</span><span class="pl-en">command</span><span class="pl-kos">,</span> <span class="pl-en">trailing</span> || <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/thor-0.20.3/lib/thor/invocation.rb</span>
<span class="pl-k">class</span> <span class="pl-v">Thor</span>
  <span class="pl-c"># FYI, this module is included in Thor.</span>
  <span class="pl-c"># And Thor is grandfather of Rails::Command::ServerCommand</span>
  <span class="pl-k">module</span> <span class="pl-v">Invocation</span>
    <span class="pl-k">def</span> <span class="pl-en">invoke_command</span><span class="pl-kos">(</span><span class="pl-s1">command</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span> <span class="pl-c"># 'invoke_command' is defined at here.</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c"># self: #&lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&gt; </span>
      <span class="pl-c"># command: {Thor::Command}#&lt;struct Thor::Command name="server" ...&gt; </span>
      <span class="pl-s1">command</span><span class="pl-kos">.</span><span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/thor-0.20.3/lib/thor/command.rb</span>
<span class="pl-k">class</span> <span class="pl-v">Thor</span>
  <span class="pl-k">class</span> <span class="pl-v">Command</span> &lt; <span class="pl-v">Struct</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-pds">:name</span><span class="pl-kos">,</span> <span class="pl-pds">:description</span><span class="pl-kos">,</span> <span class="pl-pds">:long_description</span><span class="pl-kos">,</span> <span class="pl-pds">:usage</span><span class="pl-kos">,</span> <span class="pl-pds">:options</span><span class="pl-kos">,</span> <span class="pl-pds">:ancestor_name</span><span class="pl-kos">)</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-s1">instance</span><span class="pl-kos">,</span> <span class="pl-s1">args</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c"># instance: #&lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&gt;</span>
      <span class="pl-c"># name: "server"</span>
      <span class="pl-c"># This line will invoke Rails::Command::ServerCommand#server, </span>
      <span class="pl-c"># the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.</span>
      <span class="pl-c"># I will show you how the instance method 'server' is implicitly defined. </span>
      <span class="pl-s1">instance</span><span class="pl-kos">.</span><span class="pl-en">__send__</span><span class="pl-kos">(</span><span class="pl-en">name</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span> 
    <span class="pl-k">end</span>  
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/thor-0.20.3/lib/thor.rb
class Thor
  # ...
  include Thor::Base # Will invoke hooked method 'Thor::Base.included(self)'
end

# ./gems/thor-0.20.3/lib/thor/base.rb
module Thor
  module Base
    class &lt;&lt; self
      # 'included' is a hooked method.
      # When module 'Thor::Base' is included, method 'included' is executed. 
      def included(base) 
        # base: Thor
        # this line will define `Thor.method_added`.  
        base.extend ClassMethods
        # Module 'Invocation' is included for class 'Thor' here. 
        # Because Thor is grandfather of Rails::Command::ServerCommand,
        # 'invoke_command' will be instance method of Rails::Command::ServerCommand       
        base.send :include, Invocation # 'invoke_command' is defined in module Invocation
        base.send :include, Shell
      end
    end
    
    module ClassMethods
      # 'method_added' is a hooked method.
      # When an instance method is created in Rails::Command::ServerCommand, 
      # `method_added` will be executed.
      # So, when method `perform` is defined in Rails::Command::ServerCommand,
      # `method_added` will be executed and create_command('perform') will be invoked. 
      # So in the end, method 'server' will be created by alias_method('server', 'perform').
      # And the method 'server' is for the 'server' in command `$ rails server`.
      def method_added(meth)
        # ...
        # self: {Class} Rails::Command::ServerCommand 
        create_command(meth) # meth is 'perform'. Let's step into this line.
      end
    end
  end
end

# ./gems/railties-5.2.2/lib/rails/command/base.rb
module Rails
  module Command
    # Rails::Command::Base is superclass of Rails::Command::ServerCommand
    module Base
      class &lt;&lt; self
        def create_command(meth)
          if meth == &quot;perform&quot;
            # Calling instance method 'server' of Rails::Command::ServerCommand 
            # will be transferred to call instance method 'perform'.
            alias_method('server', meth) 
          end
        end  
      end
    end
  end
end

# ./gems/thor-0.20.3/lib/thor/command.rb
class Thor
  class Command &lt; Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
    def run(instance, args = [])
      #...
      # instance: {Rails::Command::ServerCommand}#&lt;Rails::Command::ServerCommand:0x00007fa5f319bf40&gt;
      # name: 'server'.
      # Will actually invoke 'instance.perform(*args)'. 
      # Equals to invoke Rails::Command::ServerCommand#perform(*args).
      # Let's step into  Rails::Command::ServerCommand#perform.
      instance.__send__(name, *args) 
    end
  end
end

# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb
module Rails
  module Command
    class ServerCommand &lt; Base
      # This is the method will be executed when `$ rails server`.
      def perform
        # ...
        Rails::Server.new(server_options).tap do |server|
          # APP_PATH is '/path/to/your_project/config/application'.
          # require APP_PATH will create the 'Rails.application' object.
          # 'Rails.application' is 'YourProject::Application.new'.
          # Rack server will start 'Rails.application'.
          require APP_PATH
          
          Dir.chdir(Rails.application.root)
          
          server.start # Let's step into this line.
        end
      end
    end
  end
end"><pre><span class="pl-c"># ./gems/thor-0.20.3/lib/thor.rb</span>
<span class="pl-k">class</span> <span class="pl-v">Thor</span>
  <span class="pl-c"># ...</span>
  <span class="pl-en">include</span> <span class="pl-v">Thor</span>::<span class="pl-v">Base</span> <span class="pl-c"># Will invoke hooked method 'Thor::Base.included(self)'</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/thor-0.20.3/lib/thor/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Thor</span>
  <span class="pl-k">module</span> <span class="pl-v">Base</span>
    <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
      <span class="pl-c"># 'included' is a hooked method.</span>
      <span class="pl-c"># When module 'Thor::Base' is included, method 'included' is executed. </span>
      <span class="pl-k">def</span> <span class="pl-en">included</span><span class="pl-kos">(</span><span class="pl-s1">base</span><span class="pl-kos">)</span> 
        <span class="pl-c"># base: Thor</span>
        <span class="pl-c"># this line will define `Thor.method_added`.  </span>
        <span class="pl-s1">base</span><span class="pl-kos">.</span><span class="pl-en">extend</span> <span class="pl-v">ClassMethods</span>
        <span class="pl-c"># Module 'Invocation' is included for class 'Thor' here. </span>
        <span class="pl-c"># Because Thor is grandfather of Rails::Command::ServerCommand,</span>
        <span class="pl-c"># 'invoke_command' will be instance method of Rails::Command::ServerCommand       </span>
        <span class="pl-s1">base</span><span class="pl-kos">.</span><span class="pl-en">send</span> <span class="pl-pds">:include</span><span class="pl-kos">,</span> <span class="pl-v">Invocation</span> <span class="pl-c"># 'invoke_command' is defined in module Invocation</span>
        <span class="pl-s1">base</span><span class="pl-kos">.</span><span class="pl-en">send</span> <span class="pl-pds">:include</span><span class="pl-kos">,</span> <span class="pl-v">Shell</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">module</span> <span class="pl-v">ClassMethods</span>
      <span class="pl-c"># 'method_added' is a hooked method.</span>
      <span class="pl-c"># When an instance method is created in Rails::Command::ServerCommand, </span>
      <span class="pl-c"># `method_added` will be executed.</span>
      <span class="pl-c"># So, when method `perform` is defined in Rails::Command::ServerCommand,</span>
      <span class="pl-c"># `method_added` will be executed and create_command('perform') will be invoked. </span>
      <span class="pl-c"># So in the end, method 'server' will be created by alias_method('server', 'perform').</span>
      <span class="pl-c"># And the method 'server' is for the 'server' in command `$ rails server`.</span>
      <span class="pl-k">def</span> <span class="pl-en">method_added</span><span class="pl-kos">(</span><span class="pl-s1">meth</span><span class="pl-kos">)</span>
        <span class="pl-c"># ...</span>
        <span class="pl-c"># self: {Class} Rails::Command::ServerCommand </span>
        <span class="pl-en">create_command</span><span class="pl-kos">(</span><span class="pl-s1">meth</span><span class="pl-kos">)</span> <span class="pl-c"># meth is 'perform'. Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/railties-5.2.2/lib/rails/command/base.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-c"># Rails::Command::Base is superclass of Rails::Command::ServerCommand</span>
    <span class="pl-k">module</span> <span class="pl-v">Base</span>
      <span class="pl-k">class</span> &lt;&lt; <span class="pl-smi">self</span>
        <span class="pl-k">def</span> <span class="pl-en">create_command</span><span class="pl-kos">(</span><span class="pl-s1">meth</span><span class="pl-kos">)</span>
          <span class="pl-k">if</span> <span class="pl-s1">meth</span> == <span class="pl-s">"perform"</span>
            <span class="pl-c"># Calling instance method 'server' of Rails::Command::ServerCommand </span>
            <span class="pl-c"># will be transferred to call instance method 'perform'.</span>
            <span class="pl-en">alias_method</span><span class="pl-kos">(</span><span class="pl-s">'server'</span><span class="pl-kos">,</span> <span class="pl-s1">meth</span><span class="pl-kos">)</span> 
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>  
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/thor-0.20.3/lib/thor/command.rb</span>
<span class="pl-k">class</span> <span class="pl-v">Thor</span>
  <span class="pl-k">class</span> <span class="pl-v">Command</span> &lt; <span class="pl-v">Struct</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-pds">:name</span><span class="pl-kos">,</span> <span class="pl-pds">:description</span><span class="pl-kos">,</span> <span class="pl-pds">:long_description</span><span class="pl-kos">,</span> <span class="pl-pds">:usage</span><span class="pl-kos">,</span> <span class="pl-pds">:options</span><span class="pl-kos">,</span> <span class="pl-pds">:ancestor_name</span><span class="pl-kos">)</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-s1">instance</span><span class="pl-kos">,</span> <span class="pl-s1">args</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
      <span class="pl-c">#...</span>
      <span class="pl-c"># instance: {Rails::Command::ServerCommand}#&lt;Rails::Command::ServerCommand:0x00007fa5f319bf40&gt;</span>
      <span class="pl-c"># name: 'server'.</span>
      <span class="pl-c"># Will actually invoke 'instance.perform(*args)'. </span>
      <span class="pl-c"># Equals to invoke Rails::Command::ServerCommand#perform(*args).</span>
      <span class="pl-c"># Let's step into  Rails::Command::ServerCommand#perform.</span>
      <span class="pl-s1">instance</span><span class="pl-kos">.</span><span class="pl-en">__send__</span><span class="pl-kos">(</span><span class="pl-en">name</span><span class="pl-kos">,</span> *<span class="pl-s1">args</span><span class="pl-kos">)</span> 
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">module</span> <span class="pl-v">Command</span>
    <span class="pl-k">class</span> <span class="pl-v">ServerCommand</span> &lt; <span class="pl-v">Base</span>
      <span class="pl-c"># This is the method will be executed when `$ rails server`.</span>
      <span class="pl-k">def</span> <span class="pl-en">perform</span>
        <span class="pl-c"># ...</span>
        <span class="pl-v">Rails</span>::<span class="pl-v">Server</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-en">server_options</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">tap</span> <span class="pl-k">do</span> |<span class="pl-s1">server</span>|
          <span class="pl-c"># APP_PATH is '/path/to/your_project/config/application'.</span>
          <span class="pl-c"># require APP_PATH will create the 'Rails.application' object.</span>
          <span class="pl-c"># 'Rails.application' is 'YourProject::Application.new'.</span>
          <span class="pl-c"># Rack server will start 'Rails.application'.</span>
          <span class="pl-en">require</span> <span class="pl-c1">APP_PATH</span>
          
          <span class="pl-v">Dir</span><span class="pl-kos">.</span><span class="pl-en">chdir</span><span class="pl-kos">(</span><span class="pl-v">Rails</span><span class="pl-kos">.</span><span class="pl-en">application</span><span class="pl-kos">.</span><span class="pl-en">root</span><span class="pl-kos">)</span>
          
          <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">start</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Rails::Server#start</h3><a id="user-content-railsserverstart" class="anchor" aria-label="Permalink: Rails::Server#start" href="#railsserverstart"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb
module Rails
  class Server &lt; ::Rack::Server
    def start
      print_boot_information
      
      trap(:INT) do
        exit
      end
      
      create_tmp_directories
      setup_dev_caching
      
      # This line is important. Although the method name seems not.
      log_to_stdout# Let step into this line.

      super # Will invoke ::Rack::Server#start. I will show you later. 
    ensure
      puts &quot;Exiting&quot; unless @options &amp;&amp; options[:daemonize]
    end
    
    def log_to_stdout
      # 'wrapped_app' will get an well prepared Rack app from './config.ru' file.
      # It's the first time invoke 'wrapped_app'.
      # The app is an instance of YourProject::Application.
      # But the app is not created in 'wrapped_app'.
      # It has been created when `require APP_PATH` in previous code,
      # just at the 'perform' method in Rails::Command::ServerCommand.   
      wrapped_app # Let's step into this line

      # ...
    end
  end
end

# ./gems/rack-2.0.6/lib/rack/server.rb
module Rack
  class Server
    def wrapped_app
      @wrapped_app ||= 
        build_app(
          app # Let's step into this line.
        )
    end
    
    def app
      @app ||= build_app_and_options_from_config # Let's step into this line.
      @app
    end
    
    def build_app_and_options_from_config
      # ...
      # self.options[:config]: 'config.ru'. Let's step into this line.
      app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
      # ...
      app
    end
    
    # This method is called in Rails::Server#start
    def start(&amp;blk)
      #...
      wrapped_app
      #...

      # server: {Module} Rack::Handler::Puma
      # wrapped_app: {YourProject::Application} #&lt;YourProject::Application:0x00007f7fe5523f98&gt;
      server.run(wrapped_app, options, &amp;blk) # We will step into this line (Rack::Handler::Puma.run) later.
    end
  end
end

# ./gems/rack/lib/rack/builder.rb
module Rack
  module Builder
    def self.parse_file(config, opts = Server::Options.new)
      # config: 'config.ru'
      cfgfile = ::File.read(config)
      
      app = new_from_string(cfgfile, config)
      
      return app, options
    end
  
    # Let's guess what does 'run Rails.application' do in config.ru?
    # You may guess that: 
    #   Run YourProject::Application instance.
    # But 'run' maybe not what you are thinking about.
    # Because the 'self' object in 'config.ru' is #&lt;Rack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]&gt;, 
    # 'run' is an instance method of Rack::Builder.
    # Let's look at the definition of the 'run' method: 
    # def run(app)
    #   @run = app # Just set an instance variable for Rack::Builder instance.
    # end
    def self.new_from_string(builder_script, file=&quot;(rackup)&quot;)
      # Rack::Builder implements a small DSL to iteratively construct Rack applications.
      eval &quot;Rack::Builder.new {\n&quot; + builder_script + &quot;\n}.to_app&quot;,
        TOPLEVEL_BINDING, file, 0
    end
  end
end"><pre><span class="pl-c"># ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rails</span>
  <span class="pl-k">class</span> <span class="pl-v">Server</span> &lt; ::<span class="pl-v">Rack</span>::<span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">start</span>
      <span class="pl-en">print_boot_information</span>
      
      <span class="pl-en">trap</span><span class="pl-kos">(</span><span class="pl-pds">:INT</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
        <span class="pl-en">exit</span>
      <span class="pl-k">end</span>
      
      <span class="pl-en">create_tmp_directories</span>
      <span class="pl-en">setup_dev_caching</span>
      
      <span class="pl-c"># This line is important. Although the method name seems not.</span>
      <span class="pl-en">log_to_stdout</span><span class="pl-c"># Let step into this line.</span>

      <span class="pl-smi">super</span> <span class="pl-c"># Will invoke ::Rack::Server#start. I will show you later. </span>
    <span class="pl-k">ensure</span>
      <span class="pl-en">puts</span> <span class="pl-s">"Exiting"</span> <span class="pl-k">unless</span> <span class="pl-c1">@options</span> &amp;&amp; <span class="pl-en">options</span><span class="pl-kos">[</span><span class="pl-pds">:daemonize</span><span class="pl-kos">]</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">log_to_stdout</span>
      <span class="pl-c"># 'wrapped_app' will get an well prepared Rack app from './config.ru' file.</span>
      <span class="pl-c"># It's the first time invoke 'wrapped_app'.</span>
      <span class="pl-c"># The app is an instance of YourProject::Application.</span>
      <span class="pl-c"># But the app is not created in 'wrapped_app'.</span>
      <span class="pl-c"># It has been created when `require APP_PATH` in previous code,</span>
      <span class="pl-c"># just at the 'perform' method in Rails::Command::ServerCommand.   </span>
      <span class="pl-en">wrapped_app</span> <span class="pl-c"># Let's step into this line</span>

      <span class="pl-c"># ...</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/rack-2.0.6/lib/rack/server.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rack</span>
  <span class="pl-k">class</span> <span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">wrapped_app</span>
      <span class="pl-c1">@wrapped_app</span> ||= 
        <span class="pl-en">build_app</span><span class="pl-kos">(</span>
          <span class="pl-en">app</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-kos">)</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">app</span>
      <span class="pl-c1">@app</span> ||= <span class="pl-en">build_app_and_options_from_config</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-c1">@app</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">build_app_and_options_from_config</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c"># self.options[:config]: 'config.ru'. Let's step into this line.</span>
      <span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-v">Rack</span>::<span class="pl-v">Builder</span><span class="pl-kos">.</span><span class="pl-en">parse_file</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-s1">options</span><span class="pl-kos">[</span><span class="pl-pds">:config</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-en">opt_parser</span><span class="pl-kos">)</span>
      <span class="pl-c"># ...</span>
      <span class="pl-s1">app</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># This method is called in Rails::Server#start</span>
    <span class="pl-k">def</span> <span class="pl-en">start</span><span class="pl-kos">(</span>&amp;<span class="pl-s1">blk</span><span class="pl-kos">)</span>
      <span class="pl-c">#...</span>
      <span class="pl-en">wrapped_app</span>
      <span class="pl-c">#...</span>

      <span class="pl-c"># server: {Module} Rack::Handler::Puma</span>
      <span class="pl-c"># wrapped_app: {YourProject::Application} #&lt;YourProject::Application:0x00007f7fe5523f98&gt;</span>
      <span class="pl-en">server</span><span class="pl-kos">.</span><span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-en">wrapped_app</span><span class="pl-kos">,</span> <span class="pl-en">options</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">blk</span><span class="pl-kos">)</span> <span class="pl-c"># We will step into this line (Rack::Handler::Puma.run) later.</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># ./gems/rack/lib/rack/builder.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rack</span>
  <span class="pl-k">module</span> <span class="pl-v">Builder</span>
    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">parse_file</span><span class="pl-kos">(</span><span class="pl-s1">config</span><span class="pl-kos">,</span> <span class="pl-s1">opts</span> <span class="pl-c1">=</span> <span class="pl-v">Server</span>::<span class="pl-v">Options</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">)</span>
      <span class="pl-c"># config: 'config.ru'</span>
      <span class="pl-s1">cfgfile</span> <span class="pl-c1">=</span> ::<span class="pl-v">File</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-s1">config</span><span class="pl-kos">)</span>
      
      <span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-en">new_from_string</span><span class="pl-kos">(</span><span class="pl-s1">cfgfile</span><span class="pl-kos">,</span> <span class="pl-s1">config</span><span class="pl-kos">)</span>
      
      <span class="pl-k">return</span> <span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-en">options</span>
    <span class="pl-k">end</span>
  
    <span class="pl-c"># Let's guess what does 'run Rails.application' do in config.ru?</span>
    <span class="pl-c"># You may guess that: </span>
    <span class="pl-c">#   Run YourProject::Application instance.</span>
    <span class="pl-c"># But 'run' maybe not what you are thinking about.</span>
    <span class="pl-c"># Because the 'self' object in 'config.ru' is #&lt;Rack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]&gt;, </span>
    <span class="pl-c"># 'run' is an instance method of Rack::Builder.</span>
    <span class="pl-c"># Let's look at the definition of the 'run' method: </span>
    <span class="pl-c"># def run(app)</span>
    <span class="pl-c">#   @run = app # Just set an instance variable for Rack::Builder instance.</span>
    <span class="pl-c"># end</span>
    <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">new_from_string</span><span class="pl-kos">(</span><span class="pl-s1">builder_script</span><span class="pl-kos">,</span> <span class="pl-s1">file</span><span class="pl-c1">=</span><span class="pl-s">"(rackup)"</span><span class="pl-kos">)</span>
      <span class="pl-c"># Rack::Builder implements a small DSL to iteratively construct Rack applications.</span>
      <span class="pl-en">eval</span> <span class="pl-s">"Rack::Builder.new {<span class="pl-cce">\n</span>"</span> + <span class="pl-s1">builder_script</span> + <span class="pl-s">"<span class="pl-cce">\n</span>}.to_app"</span><span class="pl-kos">,</span>
        <span class="pl-c1">TOPLEVEL_BINDING</span><span class="pl-kos">,</span> <span class="pl-s1">file</span><span class="pl-kos">,</span> <span class="pl-c1">0</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Starting Puma</h3><a id="user-content-starting-puma" class="anchor" aria-label="Permalink: Starting Puma" href="#starting-puma"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">As we see in <code>Rack::Server#start</code>, there is <code>Rack::Handler::Puma.run(wrapped_app, options, &amp;blk)</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./gems/puma-3.12.0/lib/rack/handler/puma.rb
module Rack
  module Handler
    module Puma
      # This method is invoked in `Rack::Server#start`:
      # Rack::Handler::Puma.run(wrapped_app, options, &amp;blk) 
      def self.run(app, options = {})
        conf   = self.config(app, options)

        # ...
        launcher = ::Puma::Launcher.new(conf, :events =&gt; events)

        begin
          # Puma will run your app (instance of YourProject::Application)
          launcher.run # Let's step into this line.
        rescue Interrupt 
          puts &quot;* Gracefully stopping, waiting for requests to finish&quot;
          launcher.stop
          puts &quot;* Goodbye!&quot;
        end
      end
    end  
  end
end

# .gems/puma-3.12.0/lib/puma/launcher.rb
module Puma
  # Puma::Launcher is the single entry point for starting a Puma server based on user
  # configuration. It is responsible for taking user supplied arguments and resolving them
  # with configuration in `config/puma.rb` or `config/puma/&lt;env&gt;.rb`.
  #
  # It is responsible for either launching a cluster of Puma workers or a single
  # Puma server.
  class Launcher
    def initialize(conf, launcher_args={})
      @runner        = nil
      @config        = conf

      # ...
      if clustered?
        # ...
        @runner = Cluster.new(self, @events)
      else
        # For this example, it is Single.new.
        @runner = Single.new(self, @events)
      end
      
      # ...
    end
        
    def run
      #...

      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. 
      setup_signals # We will discuss this line later.
      
      set_process_title
      
      @runner.run # We will enter `Single.new(self, @events).run` here.

      case @status
      when :halt
        log &quot;* Stopping immediately!&quot;
      when :run, :stop
        graceful_stop
      when :restart
        log &quot;* Restarting...&quot;
        ENV.replace(previous_env)
        @runner.before_restart
        restart!
      when :exit
        # nothing
      end
    end
  end
end"><pre><span class="pl-c"># ./gems/puma-3.12.0/lib/rack/handler/puma.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Rack</span>
  <span class="pl-k">module</span> <span class="pl-v">Handler</span>
    <span class="pl-k">module</span> <span class="pl-v">Puma</span>
      <span class="pl-c"># This method is invoked in `Rack::Server#start`:</span>
      <span class="pl-c"># Rack::Handler::Puma.run(wrapped_app, options, &amp;blk) </span>
      <span class="pl-k">def</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
        <span class="pl-s1">conf</span>   <span class="pl-c1">=</span> <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">config</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-kos">)</span>

        <span class="pl-c"># ...</span>
        <span class="pl-s1">launcher</span> <span class="pl-c1">=</span> ::<span class="pl-v">Puma</span>::<span class="pl-v">Launcher</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">conf</span><span class="pl-kos">,</span> <span class="pl-pds">:events</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">events</span><span class="pl-kos">)</span>

        <span class="pl-k">begin</span>
          <span class="pl-c"># Puma will run your app (instance of YourProject::Application)</span>
          <span class="pl-s1">launcher</span><span class="pl-kos">.</span><span class="pl-en">run</span> <span class="pl-c"># Let's step into this line.</span>
        <span class="pl-k">rescue</span> <span class="pl-v">Interrupt</span> 
          <span class="pl-en">puts</span> <span class="pl-s">"* Gracefully stopping, waiting for requests to finish"</span>
          <span class="pl-s1">launcher</span><span class="pl-kos">.</span><span class="pl-en">stop</span>
          <span class="pl-en">puts</span> <span class="pl-s">"* Goodbye!"</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>  
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/puma-3.12.0/lib/puma/launcher.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># Puma::Launcher is the single entry point for starting a Puma server based on user</span>
  <span class="pl-c"># configuration. It is responsible for taking user supplied arguments and resolving them</span>
  <span class="pl-c"># with configuration in `config/puma.rb` or `config/puma/&lt;env&gt;.rb`.</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># It is responsible for either launching a cluster of Puma workers or a single</span>
  <span class="pl-c"># Puma server.</span>
  <span class="pl-k">class</span> <span class="pl-v">Launcher</span>
    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">conf</span><span class="pl-kos">,</span> <span class="pl-s1">launcher_args</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-c1">@runner</span>        <span class="pl-c1">=</span> <span class="pl-c1">nil</span>
      <span class="pl-c1">@config</span>        <span class="pl-c1">=</span> <span class="pl-s1">conf</span>

      <span class="pl-c"># ...</span>
      <span class="pl-k">if</span> <span class="pl-en">clustered?</span>
        <span class="pl-c"># ...</span>
        <span class="pl-c1">@runner</span> <span class="pl-c1">=</span> <span class="pl-v">Cluster</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-c1">@events</span><span class="pl-kos">)</span>
      <span class="pl-k">else</span>
        <span class="pl-c"># For this example, it is Single.new.</span>
        <span class="pl-c1">@runner</span> <span class="pl-c1">=</span> <span class="pl-v">Single</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-c1">@events</span><span class="pl-kos">)</span>
      <span class="pl-k">end</span>
      
      <span class="pl-c"># ...</span>
    <span class="pl-k">end</span>
        
    <span class="pl-k">def</span> <span class="pl-en">run</span>
      <span class="pl-c">#...</span>

      <span class="pl-c"># Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. </span>
      <span class="pl-en">setup_signals</span> <span class="pl-c"># We will discuss this line later.</span>
      
      <span class="pl-en">set_process_title</span>
      
      <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">run</span> <span class="pl-c"># We will enter `Single.new(self, @events).run` here.</span>

      <span class="pl-k">case</span> <span class="pl-c1">@status</span>
      <span class="pl-k">when</span> <span class="pl-pds">:halt</span>
        <span class="pl-en">log</span> <span class="pl-s">"* Stopping immediately!"</span>
      <span class="pl-k">when</span> <span class="pl-pds">:run</span><span class="pl-kos">,</span> <span class="pl-pds">:stop</span>
        <span class="pl-en">graceful_stop</span>
      <span class="pl-k">when</span> <span class="pl-pds">:restart</span>
        <span class="pl-en">log</span> <span class="pl-s">"* Restarting..."</span>
        <span class="pl-c1">ENV</span><span class="pl-kos">.</span><span class="pl-en">replace</span><span class="pl-kos">(</span><span class="pl-en">previous_env</span><span class="pl-kos">)</span>
        <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">before_restart</span>
        <span class="pl-en">restart!</span>
      <span class="pl-k">when</span> <span class="pl-pds">:exit</span>
        <span class="pl-c"># nothing</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/single.rb
module Puma
  # This class is instantiated by the `Puma::Launcher` and used
  # to boot and serve a Ruby application when no puma &quot;workers&quot; are needed
  # i.e. only using &quot;threaded&quot; mode. For example `$ puma -t 1:5`
  #
  # At the core of this class is running an instance of `Puma::Server` which
  # gets created via the `start_server` method from the `Puma::Runner` class
  # that this inherits from.
  class Single &lt; Runner
    def run
      # ...

      # @server: Puma::Server.new(app, @launcher.events, @options)
      @server = server = start_server # Let's step into this line.

      # ...
      thread = server.run # Let's step into this line later.
      
      # This line will suspend the main thread execution.
      # And the `thread`'s block (which is method `handle_servers`) will be executed.
      # See `Thread#join` for more information.
      # I will show you a simple example for using `thread.join`.
      # Please search `test_thread_join.rb` in this document.
      thread.join
      
      # The below line will never be executed because `thread` is always running and `thread` has joined.
      # When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed
      # because the block of `Signal.trap &quot;SIGTERM&quot;` in `Puma::Launcher#setup_signals` will be executed.
      # If you remove the line `thread.join`, the below line will be executed, 
      # but the main thread will exit after all code executed and all the threads not joined will be killed.
      puts &quot;anything which will never be executed...&quot;
    end
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/single.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># This class is instantiated by the `Puma::Launcher` and used</span>
  <span class="pl-c"># to boot and serve a Ruby application when no puma "workers" are needed</span>
  <span class="pl-c"># i.e. only using "threaded" mode. For example `$ puma -t 1:5`</span>
  <span class="pl-c">#</span>
  <span class="pl-c"># At the core of this class is running an instance of `Puma::Server` which</span>
  <span class="pl-c"># gets created via the `start_server` method from the `Puma::Runner` class</span>
  <span class="pl-c"># that this inherits from.</span>
  <span class="pl-k">class</span> <span class="pl-v">Single</span> &lt; <span class="pl-v">Runner</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span>
      <span class="pl-c"># ...</span>

      <span class="pl-c"># @server: Puma::Server.new(app, @launcher.events, @options)</span>
      <span class="pl-c1">@server</span> <span class="pl-c1">=</span> <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-en">start_server</span> <span class="pl-c"># Let's step into this line.</span>

      <span class="pl-c"># ...</span>
      <span class="pl-s1">thread</span> <span class="pl-c1">=</span> <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">run</span> <span class="pl-c"># Let's step into this line later.</span>
      
      <span class="pl-c"># This line will suspend the main thread execution.</span>
      <span class="pl-c"># And the `thread`'s block (which is method `handle_servers`) will be executed.</span>
      <span class="pl-c"># See `Thread#join` for more information.</span>
      <span class="pl-c"># I will show you a simple example for using `thread.join`.</span>
      <span class="pl-c"># Please search `test_thread_join.rb` in this document.</span>
      <span class="pl-s1">thread</span><span class="pl-kos">.</span><span class="pl-en">join</span>
      
      <span class="pl-c"># The below line will never be executed because `thread` is always running and `thread` has joined.</span>
      <span class="pl-c"># When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed</span>
      <span class="pl-c"># because the block of `Signal.trap "SIGTERM"` in `Puma::Launcher#setup_signals` will be executed.</span>
      <span class="pl-c"># If you remove the line `thread.join`, the below line will be executed, </span>
      <span class="pl-c"># but the main thread will exit after all code executed and all the threads not joined will be killed.</span>
      <span class="pl-en">puts</span> <span class="pl-s">"anything which will never be executed..."</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/runner.rb
module Puma
  # Generic class that is used by `Puma::Cluster` and `Puma::Single` to
  # serve requests. This class spawns a new instance of `Puma::Server` via
  # a call to `start_server`.
  class Runner
    def app
      @app ||= @launcher.config.app
    end
    
    def start_server
      min_t = @options[:min_threads]
      max_t = @options[:max_threads]

      server = Puma::Server.new(app, @launcher.events, @options)
      server.min_threads = min_t
      server.max_threads = max_t
      # ...

      server
    end
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/runner.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># Generic class that is used by `Puma::Cluster` and `Puma::Single` to</span>
  <span class="pl-c"># serve requests. This class spawns a new instance of `Puma::Server` via</span>
  <span class="pl-c"># a call to `start_server`.</span>
  <span class="pl-k">class</span> <span class="pl-v">Runner</span>
    <span class="pl-k">def</span> <span class="pl-en">app</span>
      <span class="pl-c1">@app</span> ||= <span class="pl-c1">@launcher</span><span class="pl-kos">.</span><span class="pl-en">config</span><span class="pl-kos">.</span><span class="pl-en">app</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">start_server</span>
      <span class="pl-s1">min_t</span> <span class="pl-c1">=</span> <span class="pl-c1">@options</span><span class="pl-kos">[</span><span class="pl-pds">:min_threads</span><span class="pl-kos">]</span>
      <span class="pl-s1">max_t</span> <span class="pl-c1">=</span> <span class="pl-c1">@options</span><span class="pl-kos">[</span><span class="pl-pds">:max_threads</span><span class="pl-kos">]</span>

      <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-v">Puma</span>::<span class="pl-v">Server</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-en">app</span><span class="pl-kos">,</span> <span class="pl-c1">@launcher</span><span class="pl-kos">.</span><span class="pl-en">events</span><span class="pl-kos">,</span> <span class="pl-c1">@options</span><span class="pl-kos">)</span>
      <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">min_threads</span> <span class="pl-c1">=</span> <span class="pl-s1">min_t</span>
      <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">max_threads</span> <span class="pl-c1">=</span> <span class="pl-s1">max_t</span>
      <span class="pl-c"># ...</span>

      <span class="pl-s1">server</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/server.rb
module Puma
  class Server
    def run(background=true)
      #...
      @status = :run
      queue_requests = @queue_requests

      # This part is important.
      # Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.
      # And the block will process the request by calling method `process_client`.
      # Let's step into this line later to see how Puma call the block.
      @thread_pool = ThreadPool.new(@min_threads,
                                    @max_threads,
                                    IOBuffer) do |client, buffer|

        # Advertise this server into the thread
        Thread.current[ThreadLocalKey] = self

        process_now = false

        if queue_requests
          process_now = client.eagerly_finish
        end  
        
        # ...
        if process_now
          # Process the request. You can look upon `client` as request.
          # If you want to know more about 'process_client', please read part 3 
          # or search 'process_client' in this document.  
          process_client(client, buffer)  
        else
          client.set_timeout @first_data_timeout
          @reactor.add client
        end
      end
      
      # ...

      if background # background: true (for this example)
        # This part is important.
        # Remember Puma created a thread here!
        # We will know that the newly created thread's job is waiting for requests.
        # When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.
        # The method `handle_servers` in thread's block will be executed immediately 
        # (executed in the newly created thread, not in the main thread).
        @thread = Thread.new { handle_servers } # Let's step into this line to see what I said.
        return @thread
      else
        handle_servers
      end
    end
    
    def handle_servers      
      sockets = [check] + @binder.ios
      pool = @thread_pool
      queue_requests = @queue_requests

      # ...
      
      # The thread is always running, because @status has been set to :run in Puma::Server#run.
      # Yes, it should always be running to transfer the incoming requests.
      while @status == :run
        begin
          # This line will cause current thread waiting until a request arrives.
          # So it will be the entry of every request!
          # sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;] 
          ios = IO.select sockets
        
          ios.first.each do |sock|
            if sock == check
              break if handle_check
            else
              if io = sock.accept_nonblock
                # You can simply look upon a Puma::Client instance as a request.  
                client = Client.new(io, @binder.env(sock))
                
                # ...
                
                # FYI, the method '&lt;&lt;' is redefined.
                # Add the request (client) to thread pool means 
                # a thread in the pool will process this request (client).   
                pool &lt;&lt; client # Let's step into this line.
                
                pool.wait_until_not_full # Let's step into this line later.
              end
            end
          end
        rescue Object =&gt; e
          @events.unknown_error self, e, &quot;Listen loop&quot;
        end
      end
    end    
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/server.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-s1">background</span><span class="pl-c1">=</span><span class="pl-c1">true</span><span class="pl-kos">)</span>
      <span class="pl-c">#...</span>
      <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:run</span>
      <span class="pl-s1">queue_requests</span> <span class="pl-c1">=</span> <span class="pl-c1">@queue_requests</span>

      <span class="pl-c"># This part is important.</span>
      <span class="pl-c"># Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.</span>
      <span class="pl-c"># And the block will process the request by calling method `process_client`.</span>
      <span class="pl-c"># Let's step into this line later to see how Puma call the block.</span>
      <span class="pl-c1">@thread_pool</span> <span class="pl-c1">=</span> <span class="pl-v">ThreadPool</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@min_threads</span><span class="pl-kos">,</span>
                                    <span class="pl-c1">@max_threads</span><span class="pl-kos">,</span>
                                    <span class="pl-v">IOBuffer</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span>|

        <span class="pl-c"># Advertise this server into the thread</span>
        <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">[</span><span class="pl-v">ThreadLocalKey</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-smi">self</span>

        <span class="pl-s1">process_now</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>

        <span class="pl-k">if</span> <span class="pl-s1">queue_requests</span>
          <span class="pl-s1">process_now</span> <span class="pl-c1">=</span> <span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">eagerly_finish</span>
        <span class="pl-k">end</span>  
        
        <span class="pl-c"># ...</span>
        <span class="pl-k">if</span> <span class="pl-s1">process_now</span>
          <span class="pl-c"># Process the request. You can look upon `client` as request.</span>
          <span class="pl-c"># If you want to know more about 'process_client', please read part 3 </span>
          <span class="pl-c"># or search 'process_client' in this document.  </span>
          <span class="pl-en">process_client</span><span class="pl-kos">(</span><span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span><span class="pl-kos">)</span>  
        <span class="pl-k">else</span>
          <span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">set_timeout</span> <span class="pl-c1">@first_data_timeout</span>
          <span class="pl-c1">@reactor</span><span class="pl-kos">.</span><span class="pl-en">add</span> <span class="pl-s1">client</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
      
      <span class="pl-c"># ...</span>

      <span class="pl-k">if</span> <span class="pl-s1">background</span> <span class="pl-c"># background: true (for this example)</span>
        <span class="pl-c"># This part is important.</span>
        <span class="pl-c"># Remember Puma created a thread here!</span>
        <span class="pl-c"># We will know that the newly created thread's job is waiting for requests.</span>
        <span class="pl-c"># When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.</span>
        <span class="pl-c"># The method `handle_servers` in thread's block will be executed immediately </span>
        <span class="pl-c"># (executed in the newly created thread, not in the main thread).</span>
        <span class="pl-c1">@thread</span> <span class="pl-c1">=</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-kos">{</span> <span class="pl-en">handle_servers</span> <span class="pl-kos">}</span> <span class="pl-c"># Let's step into this line to see what I said.</span>
        <span class="pl-k">return</span> <span class="pl-c1">@thread</span>
      <span class="pl-k">else</span>
        <span class="pl-en">handle_servers</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">handle_servers</span>      
      <span class="pl-s1">sockets</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-en">check</span><span class="pl-kos">]</span> + <span class="pl-c1">@binder</span><span class="pl-kos">.</span><span class="pl-en">ios</span>
      <span class="pl-s1">pool</span> <span class="pl-c1">=</span> <span class="pl-c1">@thread_pool</span>
      <span class="pl-s1">queue_requests</span> <span class="pl-c1">=</span> <span class="pl-c1">@queue_requests</span>

      <span class="pl-c"># ...</span>
      
      <span class="pl-c"># The thread is always running, because @status has been set to :run in Puma::Server#run.</span>
      <span class="pl-c"># Yes, it should always be running to transfer the incoming requests.</span>
      <span class="pl-k">while</span> <span class="pl-c1">@status</span> == <span class="pl-pds">:run</span>
        <span class="pl-k">begin</span>
          <span class="pl-c"># This line will cause current thread waiting until a request arrives.</span>
          <span class="pl-c"># So it will be the entry of every request!</span>
          <span class="pl-c"># sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;] </span>
          <span class="pl-s1">ios</span> <span class="pl-c1">=</span> <span class="pl-c1">IO</span><span class="pl-kos">.</span><span class="pl-en">select</span> <span class="pl-s1">sockets</span>
        
          <span class="pl-s1">ios</span><span class="pl-kos">.</span><span class="pl-en">first</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">sock</span>|
            <span class="pl-k">if</span> <span class="pl-s1">sock</span> == <span class="pl-en">check</span>
              <span class="pl-k">break</span> <span class="pl-k">if</span> <span class="pl-en">handle_check</span>
            <span class="pl-k">else</span>
              <span class="pl-k">if</span> <span class="pl-s1">io</span> <span class="pl-c1">=</span> <span class="pl-s1">sock</span><span class="pl-kos">.</span><span class="pl-en">accept_nonblock</span>
                <span class="pl-c"># You can simply look upon a Puma::Client instance as a request.  </span>
                <span class="pl-s1">client</span> <span class="pl-c1">=</span> <span class="pl-v">Client</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">io</span><span class="pl-kos">,</span> <span class="pl-c1">@binder</span><span class="pl-kos">.</span><span class="pl-en">env</span><span class="pl-kos">(</span><span class="pl-s1">sock</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
                
                <span class="pl-c"># ...</span>
                
                <span class="pl-c"># FYI, the method '&lt;&lt;' is redefined.</span>
                <span class="pl-c"># Add the request (client) to thread pool means </span>
                <span class="pl-c"># a thread in the pool will process this request (client).   </span>
                <span class="pl-s1">pool</span> &lt;&lt; <span class="pl-s1">client</span> <span class="pl-c"># Let's step into this line.</span>
                
                <span class="pl-s1">pool</span><span class="pl-kos">.</span><span class="pl-en">wait_until_not_full</span> <span class="pl-c"># Let's step into this line later.</span>
              <span class="pl-k">end</span>
            <span class="pl-k">end</span>
          <span class="pl-k">end</span>
        <span class="pl-k">rescue</span> <span class="pl-v">Object</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">e</span>
          <span class="pl-c1">@events</span><span class="pl-kos">.</span><span class="pl-en">unknown_error</span> <span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-en">e</span><span class="pl-kos">,</span> <span class="pl-s">"Listen loop"</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>    
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/thread_pool.rb
module Puma
  class ThreadPool
    # Maintain a minimum of +min+ and maximum of +max+ threads
    # in the pool.
    #
    # The block passed is the work that will be performed in each
    # thread.
    #
    def initialize(min, max, *extra, &amp;block)
      #..
      @mutex = Mutex.new
      @todo = [] # @todo is requests (in Puma, they are Puma::Client instances) which need to be processed.  
      @spawned = 0 # the count of @spawned threads
      @min = Integer(min) # @min threads count
      @max = Integer(max) # @max threads count
      @block = block # block will be called in method `spawn_thread` to processed a request.    
      @workers = []
      @reaper = nil

      @mutex.synchronize do
        @min.times { spawn_thread } # Puma spawns @min count threads.
      end
    end
    
    def spawn_thread
      @spawned += 1

      # Create a new Thread now.
      # The block of the thread will be executed immediately and separately from the calling thread (main thread).
      th = Thread.new(@spawned) do |spawned|
        # Thread name is new in Ruby 2.3
        Thread.current.name = 'puma %03i' % spawned if Thread.current.respond_to?(:name=)
        block = @block
        mutex = @mutex
        #...

        extra = @extra.map { |i| i.new }

        # Pay attention to here: 
        # 'while true' means this part will always be running.
        # And there will be @min count threads always running!
        # Puma uses these threads to process requests. 
        # The line: 'not_empty.wait(mutex)' will make current thread waiting.  
        while true
          work = nil

          continue = true

          mutex.synchronize do
            while todo.empty?
              if @trim_requested &gt; 0
                @trim_requested -= 1
                continue = false
                not_full.signal
                break
              end

              if @shutdown
                continue = false
                break
              end

              @waiting += 1 # `@waiting` is the waiting threads count.
              not_full.signal
              
              # This line will cause current thread waiting
              # until `not_empty.signal` executed in some other place to wake it up .
              # Actually, `not_empty.signal` is located at `def &lt;&lt;(work)` in the same file.
              # You can search `def &lt;&lt;(work)` in this document.
              # Method `&lt;&lt;` is used in method `handle_servers`: `pool &lt;&lt; client` in Puma::Server#run.
              # `pool &lt;&lt; client` means add a request to the thread pool, 
              # and then the waked up thread will process the request. 
              not_empty.wait mutex
              
              @waiting -= 1
            end

            # `work` is the request (in Puma, it's Puma::Client instance) which need to be processed.
            work = todo.shift if continue  
          end

          break unless continue

          if @clean_thread_locals
            ThreadPool.clean_thread_locals
          end

          begin
            # `block.call` will switch program to the block definition part.
            # The block definition part is in `Puma::Server#run`:
            # @thread_pool = ThreadPool.new(@min_threads,
            #                               @max_threads,
            #                               IOBuffer) do |client, buffer| #...; end
            # So please search `ThreadPool.new` in this document to look back.
            block.call(work, *extra)
          rescue Exception =&gt; e
            STDERR.puts &quot;Error reached top of thread-pool: #{e.message} (#{e.class})&quot;
          end
        end

        mutex.synchronize do
          @spawned -= 1
          @workers.delete th
        end
      end # end of the Thread.new.

      @workers &lt;&lt; th

      th
    end
    
    def wait_until_not_full
      @mutex.synchronize do
        while true
          return if @shutdown

          # If we can still spin up new threads and there
          # is work queued that cannot be handled by waiting
          # threads, then accept more work until we would
          # spin up the max number of threads.
          return if @todo.size - @waiting &lt; @max - @spawned

          @not_full.wait @mutex 
        end
      end
    end
    
    # Add +work+ to the todo list for a Thread to pickup and process.
    def &lt;&lt;(work)
      @mutex.synchronize do
        if @shutdown
          raise &quot;Unable to add work while shutting down&quot;
        end
        
        # work: #&lt;Puma::Client:0x00007ff114ece6b0&gt;
        # You can look upon Puma::Client instance as a request.
        @todo &lt;&lt; work

        if @waiting &lt; @todo.size and @spawned &lt; @max
          spawn_thread # Create one more thread to process request. 
        end

        # Wake up the waiting thread to process the request.
        # The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.
        # This code is in `spawn_thread`:
        # while true 
        #   # ...
        #   not_empty.wait mutex
        #   # ... 
        #   block.call(work, *extra) # This line will process the request.
        # end 
        @not_empty.signal  
      end
    end
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/thread_pool.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">ThreadPool</span>
    <span class="pl-c"># Maintain a minimum of +min+ and maximum of +max+ threads</span>
    <span class="pl-c"># in the pool.</span>
    <span class="pl-c">#</span>
    <span class="pl-c"># The block passed is the work that will be performed in each</span>
    <span class="pl-c"># thread.</span>
    <span class="pl-c">#</span>
    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">min</span><span class="pl-kos">,</span> <span class="pl-s1">max</span><span class="pl-kos">,</span> *<span class="pl-s1">extra</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-c">#..</span>
      <span class="pl-c1">@mutex</span> <span class="pl-c1">=</span> <span class="pl-v">Mutex</span><span class="pl-kos">.</span><span class="pl-en">new</span>
      <span class="pl-c1">@todo</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c"># @todo is requests (in Puma, they are Puma::Client instances) which need to be processed.  </span>
      <span class="pl-c1">@spawned</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span> <span class="pl-c"># the count of @spawned threads</span>
      <span class="pl-c1">@min</span> <span class="pl-c1">=</span> <span class="pl-en">Integer</span><span class="pl-kos">(</span><span class="pl-s1">min</span><span class="pl-kos">)</span> <span class="pl-c"># @min threads count</span>
      <span class="pl-c1">@max</span> <span class="pl-c1">=</span> <span class="pl-en">Integer</span><span class="pl-kos">(</span><span class="pl-s1">max</span><span class="pl-kos">)</span> <span class="pl-c"># @max threads count</span>
      <span class="pl-c1">@block</span> <span class="pl-c1">=</span> <span class="pl-s1">block</span> <span class="pl-c"># block will be called in method `spawn_thread` to processed a request.    </span>
      <span class="pl-c1">@workers</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span>
      <span class="pl-c1">@reaper</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>

      <span class="pl-c1">@mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-c1">@min</span><span class="pl-kos">.</span><span class="pl-en">times</span> <span class="pl-kos">{</span> <span class="pl-en">spawn_thread</span> <span class="pl-kos">}</span> <span class="pl-c"># Puma spawns @min count threads.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">spawn_thread</span>
      <span class="pl-c1">@spawned</span> += <span class="pl-c1">1</span>

      <span class="pl-c"># Create a new Thread now.</span>
      <span class="pl-c"># The block of the thread will be executed immediately and separately from the calling thread (main thread).</span>
      <span class="pl-s1">th</span> <span class="pl-c1">=</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@spawned</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">spawned</span>|
        <span class="pl-c"># Thread name is new in Ruby 2.3</span>
        <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">name</span> <span class="pl-c1">=</span> <span class="pl-s">'puma %03i'</span> % <span class="pl-s1">spawned</span> <span class="pl-k">if</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">respond_to?</span><span class="pl-kos">(</span><span class="pl-pds">:name=</span><span class="pl-kos">)</span>
        <span class="pl-s1">block</span> <span class="pl-c1">=</span> <span class="pl-c1">@block</span>
        <span class="pl-s1">mutex</span> <span class="pl-c1">=</span> <span class="pl-c1">@mutex</span>
        <span class="pl-c">#...</span>

        <span class="pl-s1">extra</span> <span class="pl-c1">=</span> <span class="pl-c1">@extra</span><span class="pl-kos">.</span><span class="pl-en">map</span> <span class="pl-kos">{</span> |<span class="pl-s1">i</span>| <span class="pl-s1">i</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-kos">}</span>

        <span class="pl-c"># Pay attention to here: </span>
        <span class="pl-c"># 'while true' means this part will always be running.</span>
        <span class="pl-c"># And there will be @min count threads always running!</span>
        <span class="pl-c"># Puma uses these threads to process requests. </span>
        <span class="pl-c"># The line: 'not_empty.wait(mutex)' will make current thread waiting.  </span>
        <span class="pl-k">while</span> <span class="pl-c1">true</span>
          <span class="pl-s1">work</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>

          <span class="pl-s1">continue</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>

          <span class="pl-s1">mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
            <span class="pl-k">while</span> <span class="pl-en">todo</span><span class="pl-kos">.</span><span class="pl-en">empty?</span>
              <span class="pl-k">if</span> <span class="pl-c1">@trim_requested</span> &gt; <span class="pl-c1">0</span>
                <span class="pl-c1">@trim_requested</span> -= <span class="pl-c1">1</span>
                <span class="pl-s1">continue</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>
                <span class="pl-en">not_full</span><span class="pl-kos">.</span><span class="pl-en">signal</span>
                <span class="pl-k">break</span>
              <span class="pl-k">end</span>

              <span class="pl-k">if</span> <span class="pl-c1">@shutdown</span>
                <span class="pl-s1">continue</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>
                <span class="pl-k">break</span>
              <span class="pl-k">end</span>

              <span class="pl-c1">@waiting</span> += <span class="pl-c1">1</span> <span class="pl-c"># `@waiting` is the waiting threads count.</span>
              <span class="pl-en">not_full</span><span class="pl-kos">.</span><span class="pl-en">signal</span>
              
              <span class="pl-c"># This line will cause current thread waiting</span>
              <span class="pl-c"># until `not_empty.signal` executed in some other place to wake it up .</span>
              <span class="pl-c"># Actually, `not_empty.signal` is located at `def &lt;&lt;(work)` in the same file.</span>
              <span class="pl-c"># You can search `def &lt;&lt;(work)` in this document.</span>
              <span class="pl-c"># Method `&lt;&lt;` is used in method `handle_servers`: `pool &lt;&lt; client` in Puma::Server#run.</span>
              <span class="pl-c"># `pool &lt;&lt; client` means add a request to the thread pool, </span>
              <span class="pl-c"># and then the waked up thread will process the request. </span>
              <span class="pl-en">not_empty</span><span class="pl-kos">.</span><span class="pl-en">wait</span> <span class="pl-s1">mutex</span>
              
              <span class="pl-c1">@waiting</span> -= <span class="pl-c1">1</span>
            <span class="pl-k">end</span>

            <span class="pl-c"># `work` is the request (in Puma, it's Puma::Client instance) which need to be processed.</span>
            <span class="pl-s1">work</span> <span class="pl-c1">=</span> <span class="pl-en">todo</span><span class="pl-kos">.</span><span class="pl-en">shift</span> <span class="pl-k">if</span> <span class="pl-s1">continue</span>  
          <span class="pl-k">end</span>

          <span class="pl-k">break</span> <span class="pl-k">unless</span> <span class="pl-s1">continue</span>

          <span class="pl-k">if</span> <span class="pl-c1">@clean_thread_locals</span>
            <span class="pl-v">ThreadPool</span><span class="pl-kos">.</span><span class="pl-en">clean_thread_locals</span>
          <span class="pl-k">end</span>

          <span class="pl-k">begin</span>
            <span class="pl-c"># `block.call` will switch program to the block definition part.</span>
            <span class="pl-c"># The block definition part is in `Puma::Server#run`:</span>
            <span class="pl-c"># @thread_pool = ThreadPool.new(@min_threads,</span>
            <span class="pl-c">#                               @max_threads,</span>
            <span class="pl-c">#                               IOBuffer) do |client, buffer| #...; end</span>
            <span class="pl-c"># So please search `ThreadPool.new` in this document to look back.</span>
            <span class="pl-s1">block</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-s1">work</span><span class="pl-kos">,</span> *<span class="pl-s1">extra</span><span class="pl-kos">)</span>
          <span class="pl-k">rescue</span> <span class="pl-v">Exception</span> <span class="pl-c1">=&gt;</span> <span class="pl-en">e</span>
            <span class="pl-c1">STDERR</span><span class="pl-kos">.</span><span class="pl-en">puts</span> <span class="pl-s">"Error reached top of thread-pool: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">e</span><span class="pl-kos">.</span><span class="pl-en">message</span><span class="pl-kos">}</span></span> (<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">e</span><span class="pl-kos">.</span><span class="pl-en">class</span><span class="pl-kos">}</span></span>)"</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>

        <span class="pl-s1">mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
          <span class="pl-c1">@spawned</span> -= <span class="pl-c1">1</span>
          <span class="pl-c1">@workers</span><span class="pl-kos">.</span><span class="pl-en">delete</span> <span class="pl-s1">th</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span> <span class="pl-c"># end of the Thread.new.</span>

      <span class="pl-c1">@workers</span> &lt;&lt; <span class="pl-s1">th</span>

      <span class="pl-s1">th</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">wait_until_not_full</span>
      <span class="pl-c1">@mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-k">while</span> <span class="pl-c1">true</span>
          <span class="pl-k">return</span> <span class="pl-k">if</span> <span class="pl-c1">@shutdown</span>

          <span class="pl-c"># If we can still spin up new threads and there</span>
          <span class="pl-c"># is work queued that cannot be handled by waiting</span>
          <span class="pl-c"># threads, then accept more work until we would</span>
          <span class="pl-c"># spin up the max number of threads.</span>
          <span class="pl-k">return</span> <span class="pl-k">if</span> <span class="pl-c1">@todo</span><span class="pl-kos">.</span><span class="pl-en">size</span> - <span class="pl-c1">@waiting</span> &lt; <span class="pl-c1">@max</span> - <span class="pl-c1">@spawned</span>

          <span class="pl-c1">@not_full</span><span class="pl-kos">.</span><span class="pl-en">wait</span> <span class="pl-c1">@mutex</span> 
        <span class="pl-k">end</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Add +work+ to the todo list for a Thread to pickup and process.</span>
    <span class="pl-k">def</span> &lt;&lt;<span class="pl-kos">(</span><span class="pl-s1">work</span><span class="pl-kos">)</span>
      <span class="pl-c1">@mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-k">if</span> <span class="pl-c1">@shutdown</span>
          <span class="pl-en">raise</span> <span class="pl-s">"Unable to add work while shutting down"</span>
        <span class="pl-k">end</span>
        
        <span class="pl-c"># work: #&lt;Puma::Client:0x00007ff114ece6b0&gt;</span>
        <span class="pl-c"># You can look upon Puma::Client instance as a request.</span>
        <span class="pl-c1">@todo</span> &lt;&lt; <span class="pl-s1">work</span>

        <span class="pl-k">if</span> <span class="pl-c1">@waiting</span> &lt; <span class="pl-c1">@todo</span><span class="pl-kos">.</span><span class="pl-en">size</span> <span class="pl-k">and</span> <span class="pl-c1">@spawned</span> &lt; <span class="pl-c1">@max</span>
          <span class="pl-en">spawn_thread</span> <span class="pl-c"># Create one more thread to process request. </span>
        <span class="pl-k">end</span>

        <span class="pl-c"># Wake up the waiting thread to process the request.</span>
        <span class="pl-c"># The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.</span>
        <span class="pl-c"># This code is in `spawn_thread`:</span>
        <span class="pl-c"># while true </span>
        <span class="pl-c">#   # ...</span>
        <span class="pl-c">#   not_empty.wait mutex</span>
        <span class="pl-c">#   # ... </span>
        <span class="pl-c">#   block.call(work, *extra) # This line will process the request.</span>
        <span class="pl-c"># end </span>
        <span class="pl-c1">@not_empty</span><span class="pl-kos">.</span><span class="pl-en">signal</span>  
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Conclusion</h3><a id="user-content-conclusion" class="anchor" aria-label="Permalink: Conclusion" href="#conclusion"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">In conclusion, <code>$ rails server</code> will execute <code>Rails::Command::ServerCommand#perform</code>.</p>
<p dir="auto">In <code>#perform</code>, call <code>Rails::Server#start</code>. Then call <code>Rack::Server#start</code>.</p>
<p dir="auto">Then call <code>Rack::Handler::Puma.run(YourProject::Application.new)</code>.</p>
<p dir="auto">In <code>.run</code>, Puma will new a always running Thread for <code>ios = IO.select(#&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;)</code>.</p>
<p dir="auto">Request is created from <code>ios</code> object.</p>
<p dir="auto">A thread in Puma threadPool will process the request.</p>
<p dir="auto">The thread will invoke Rack apps' <code>call</code> to get the response for the request.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Exiting Puma</h3><a id="user-content-exiting-puma" class="anchor" aria-label="Permalink: Exiting Puma" href="#exiting-puma"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Process and Thread</h4><a id="user-content-process-and-thread" class="anchor" aria-label="Permalink: Process and Thread" href="#process-and-thread"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Because Puma is using multiple threads, we need to have some basic concepts about Process and Thread.</p>
<p dir="auto">This link is good for you to obtain the concepts: <a href="https://stackoverflow.com/questions/4894609/will-a-cpu-process-have-at-least-one-thread" rel="nofollow">Process and Thread</a></p>
<p dir="auto">In the next part, you will often see <code>thread.join</code>.</p>
<p dir="auto">I will use two simple example to tell what does <code>thread.join</code> do.</p>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Example one</h5><a id="user-content-example-one" class="anchor" aria-label="Permalink: Example one" href="#example-one"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Try to run <code>test_thread_join.rb</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./test_thread_join.rb
thread = Thread.new() do
  3.times do |n|
    puts &quot;~~~~ &quot; + n.to_s
  end
end

# sleep 1
puts &quot;==== I am the main thread.&quot;

# thread.join # Try to uncomment these two lines to see the differences.
# puts &quot;==== after thread.join&quot;"><pre><span class="pl-c"># ./test_thread_join.rb</span>
<span class="pl-s1">thread</span> <span class="pl-c1">=</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-k">do</span>
  <span class="pl-c1">3</span><span class="pl-kos">.</span><span class="pl-en">times</span> <span class="pl-k">do</span> |<span class="pl-s1">n</span>|
    <span class="pl-en">puts</span> <span class="pl-s">"~~~~ "</span> + <span class="pl-s1">n</span><span class="pl-kos">.</span><span class="pl-en">to_s</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># sleep 1</span>
<span class="pl-en">puts</span> <span class="pl-s">"==== I am the main thread."</span>

<span class="pl-c"># thread.join # Try to uncomment these two lines to see the differences.</span>
<span class="pl-c"># puts "==== after thread.join"</span></pre></div>
<p dir="auto">You will find that if there is no <code>thread.join</code>, you can see</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="==== I am the main thread.
==== after thread.join
~~~~ 0
~~~~ 1
~~~~ 2"><pre lang="log" class="notranslate"><code>==== I am the main thread.
==== after thread.join
~~~~ 0
~~~~ 1
~~~~ 2
</code></pre></div>
<p dir="auto">in console.</p>
<p dir="auto">After you added <code>thread.join</code>, you can see:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="==== I am the main thread.
~~~~ 0
~~~~ 1
~~~~ 2
==== after thread.join"><pre lang="log" class="notranslate"><code>==== I am the main thread.
~~~~ 0
~~~~ 1
~~~~ 2
==== after thread.join
</code></pre></div>
<p dir="auto">in console.</p>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Example two</h5><a id="user-content-example-two" class="anchor" aria-label="Permalink: Example two" href="#example-two"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Try to run <code>test_thread_join2.rb</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# ./test_thread_join2.rb
arr = [
  Thread.new do
    puts 'I am arr[0]'
    sleep 1
    puts 'After arr[0]'
  end,
  Thread.new do
    puts 'I am arr[1]'
    sleep 5
    puts 'After arr[1]'
  end,
  Thread.new do
    puts 'I am arr[2]'
    sleep 8
    puts 'After arr[2]'
  end
]

puts &quot;Thread.list.size:  #{Thread.list.size}&quot; # returns 4 (including the main thread)

sleep 2

arr.each { |thread| puts &quot;~~~~~ #{thread}&quot; }

puts &quot;Thread.list.size:  #{Thread.list.size}&quot; # returns 3 (because arr[0] is dead)

arr[1].join # uncomment to see differences

arr.each { |thread| puts &quot;~~~~~ #{thread}&quot; }

sleep 7
puts &quot;Exit main thread&quot;"><pre><span class="pl-c"># ./test_thread_join2.rb</span>
<span class="pl-s1">arr</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
  <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-k">do</span>
    <span class="pl-en">puts</span> <span class="pl-s">'I am arr[0]'</span>
    <span class="pl-en">sleep</span> <span class="pl-c1">1</span>
    <span class="pl-en">puts</span> <span class="pl-s">'After arr[0]'</span>
  <span class="pl-k">end</span><span class="pl-kos">,</span>
  <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-k">do</span>
    <span class="pl-en">puts</span> <span class="pl-s">'I am arr[1]'</span>
    <span class="pl-en">sleep</span> <span class="pl-c1">5</span>
    <span class="pl-en">puts</span> <span class="pl-s">'After arr[1]'</span>
  <span class="pl-k">end</span><span class="pl-kos">,</span>
  <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-k">do</span>
    <span class="pl-en">puts</span> <span class="pl-s">'I am arr[2]'</span>
    <span class="pl-en">sleep</span> <span class="pl-c1">8</span>
    <span class="pl-en">puts</span> <span class="pl-s">'After arr[2]'</span>
  <span class="pl-k">end</span>
<span class="pl-kos">]</span>

<span class="pl-en">puts</span> <span class="pl-s">"Thread.list.size:  <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">list</span><span class="pl-kos">.</span><span class="pl-en">size</span><span class="pl-kos">}</span></span>"</span> <span class="pl-c"># returns 4 (including the main thread)</span>

<span class="pl-en">sleep</span> <span class="pl-c1">2</span>

<span class="pl-s1">arr</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-kos">{</span> |<span class="pl-s1">thread</span>| <span class="pl-en">puts</span> <span class="pl-s">"~~~~~ <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-s1">thread</span><span class="pl-kos">}</span></span>"</span> <span class="pl-kos">}</span>

<span class="pl-en">puts</span> <span class="pl-s">"Thread.list.size:  <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">list</span><span class="pl-kos">.</span><span class="pl-en">size</span><span class="pl-kos">}</span></span>"</span> <span class="pl-c"># returns 3 (because arr[0] is dead)</span>

<span class="pl-s1">arr</span><span class="pl-kos">[</span><span class="pl-c1">1</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">join</span> <span class="pl-c"># uncomment to see differences</span>

<span class="pl-s1">arr</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-kos">{</span> |<span class="pl-s1">thread</span>| <span class="pl-en">puts</span> <span class="pl-s">"~~~~~ <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-s1">thread</span><span class="pl-kos">}</span></span>"</span> <span class="pl-kos">}</span>

<span class="pl-en">sleep</span> <span class="pl-c1">7</span>
<span class="pl-en">puts</span> <span class="pl-s">"Exit main thread"</span></pre></div>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Send <code>SIGTERM</code> to Puma</h4><a id="user-content-send-sigterm-to-puma" class="anchor" aria-label="Permalink: Send SIGTERM to Puma" href="#send-sigterm-to-puma"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When you stop Puma by running <code>$ kill -s SIGTERM puma_process_id</code>, you will enter <code>setup_signals</code> in <code>Puma::Launcher#run</code>.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/launcher.rb
module Puma
  # Puma::Launcher is the single entry point for starting a Puma server based on user
  # configuration.
  class Launcher
    def run
      #...

      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. 
      setup_signals # Let's step into this line.
      
      set_process_title
      
      @runner.run

      # ...
    end
    
    # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.
    # Signal.list #=&gt; {&quot;EXIT&quot;=&gt;0, &quot;HUP&quot;=&gt;1, &quot;INT&quot;=&gt;2, &quot;QUIT&quot;=&gt;3, &quot;ILL&quot;=&gt;4, &quot;TRAP&quot;=&gt;5, &quot;IOT&quot;=&gt;6, &quot;ABRT&quot;=&gt;6, &quot;FPE&quot;=&gt;8, &quot;KILL&quot;=&gt;9, &quot;BUS&quot;=&gt;7, &quot;SEGV&quot;=&gt;11, &quot;SYS&quot;=&gt;31, &quot;PIPE&quot;=&gt;13, &quot;ALRM&quot;=&gt;14, &quot;TERM&quot;=&gt;15, &quot;URG&quot;=&gt;23, &quot;STOP&quot;=&gt;19, &quot;TSTP&quot;=&gt;20, &quot;CONT&quot;=&gt;18, &quot;CHLD&quot;=&gt;17, &quot;CLD&quot;=&gt;17, &quot;TTIN&quot;=&gt;21, &quot;TTOU&quot;=&gt;22, &quot;IO&quot;=&gt;29, &quot;XCPU&quot;=&gt;24, &quot;XFSZ&quot;=&gt;25, &quot;VTALRM&quot;=&gt;26, &quot;PROF&quot;=&gt;27, &quot;WINCH&quot;=&gt;28, &quot;USR1&quot;=&gt;10, &quot;USR2&quot;=&gt;12, &quot;PWR&quot;=&gt;30, &quot;POLL&quot;=&gt;29}
    # Press `Control + C` to quit means 'SIGINT'.
    def setup_signals
      begin
        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap &quot;SIGTERM&quot;`.
        Signal.trap &quot;SIGTERM&quot; do
          graceful_stop # Let's step into this line.

          raise SignalException, &quot;SIGTERM&quot;
        end
      rescue Exception
        log &quot;*** SIGTERM not implemented, signal based gracefully stopping unavailable!&quot;
      end
            
      begin
        Signal.trap &quot;SIGUSR2&quot; do
          restart
        end
      rescue Exception
        log &quot;*** SIGUSR2 not implemented, signal based restart unavailable!&quot;
      end

      begin
        Signal.trap &quot;SIGUSR1&quot; do
          phased_restart
        end
      rescue Exception
        log &quot;*** SIGUSR1 not implemented, signal based restart unavailable!&quot;
      end

      begin
        Signal.trap &quot;SIGINT&quot; do
          if Puma.jruby?
            @status = :exit
            graceful_stop
            exit
          end

          stop
        end
      rescue Exception
        log &quot;*** SIGINT not implemented, signal based gracefully stopping unavailable!&quot;
      end

      begin
        Signal.trap &quot;SIGHUP&quot; do
          if @runner.redirected_io?
            @runner.redirect_io
          else
            stop
          end
        end
      rescue Exception
        log &quot;*** SIGHUP not implemented, signal based logs reopening unavailable!&quot;
      end
    end
    
    def graceful_stop
      # @runner: instance of Puma::Single (for this example)
      @runner.stop_blocked # Let's step into this line.
      log &quot;=== puma shutdown: #{Time.now} ===&quot;
      log &quot;- Goodbye!&quot;
    end
  end
end

# .gems/puma-3.12.0/lib/puma/launcher.rb
module Puma
  class Single &lt; Runner
    def run
      # ...

      # @server: Puma::Server.new(app, @launcher.events, @options)
      @server = server = start_server # Let's step into this line.

      # ...
      thread = server.run
      
      # This line will suspend the main thread execution.
      # And the `thread`'s block (which is the method `handle_servers`) will be executed.  
      thread.join
    end
      
    def stop_blocked
      log &quot;- Gracefully stopping, waiting for requests to finish&quot;
      @control.stop(true) if @control
      # @server: instance of Puma::Server
      @server.stop(true) # Let's step into this line
    end
  end
end

# .gems/puma-3.12.0/lib/puma/server.rb
module Puma
  class Server
    def initialize(app, events=Events.stdio, options={})
      # 'Puma::Util.pipe' returns `IO.pipe`.
      @check, @notify = Puma::Util.pipe # @check, @notify is a pair.

      @status = :stop
    end
      
    def run(background=true)
      # ...
      @thread_pool = ThreadPool.new(@min_threads,
                                    @max_threads,
                                    IOBuffer) do |client, buffer|

        #...
        # Process the request.
        process_client(client, buffer)  
        #...
      end
      
      # 'Thread.current.object_id' returns '70144214949920', 
      # which is the same as the 'Thread.current.object_id' in Puma::Server#stop.
      # Current thread is the main thread here.
      puts &quot;#{Thread.current.object_id}&quot;
      
      # The created @thread is the @thread in `stop` method below.
      @thread = Thread.new {
        # FYI, this is in the Puma starting process.      
        # 'Thread.current.object_id' returns '70144220123860', 
        # which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run
        # def handle_servers
        #   begin
        #     # ...
        #   ensure
        #     # FYI, the 'ensure' part is in the Puma stopping process.
        #     puts &quot;#{Thread.current.object_id}&quot; # returns '70144220123860' too.
        #   end
        # end
        puts &quot;#{Thread.current.object_id}&quot; # returns '70144220123860'
        
        handle_servers
      }
      return @thread
    end
      
    # Stops the acceptor thread and then causes the worker threads to finish
    # off the request queue before finally exiting.
    def stop(sync=false)
      # This line will set '@status = :stop',
      # and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.
      # So that the code after `ios = IO.select sockets` will be executed.   
      notify_safely(STOP_COMMAND) # Let's step into this line.
      
      # 'Thread.current.object_id' returns '70144214949920', 
      # which is the same as the 'Thread.current.object_id' in Puma::Server#run.
      # Current thread is exactly the main thread here.
      puts &quot;#{Thread.current.object_id}&quot;
      
      # The @thread is just the always running Thread created in `Puma::Server#run`.
      # Please look at method `Puma::Server#run`.
      # `@thread.join` will suspend the main thread execution.
      # And the code in @thread will continue be executed.
      @thread.join if @thread &amp;&amp; sync
    end
    
    def notify_safely(message)
      @notify &lt;&lt; message
    end
    
    def handle_servers
      begin
        check = @check
        # sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;]
        sockets = [check] + @binder.ios
        pool = @thread_pool
        #...
 
        while @status == :run
          # After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.
          # FYI, `@check, @notify = IO.pipe`.
          # def notify_safely(message)
          #   @notify &lt;&lt; message
          # end
          # sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;]
          ios = IO.select sockets
            
          ios.first.each do |sock|
            if sock == check
              # The @status is updated to :stop for this example in `handle_check`.
              break if handle_check # Let's step into this line.
            else
              if io = sock.accept_nonblock
                client = Client.new(io, @binder.env(sock))
                
                # ...
                pool &lt;&lt; client
                pool.wait_until_not_full
              end
            end
          end
        end
        
        # Let's step into `graceful_shutdown`.
        graceful_shutdown if @status == :stop || @status == :restart
        
      # ...
      ensure
        # FYI, the 'ensure' part is in the Puma stopping process.
        # 'Thread.current.object_id' returns '70144220123860', 
        # which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run
        # @thread = Thread.new do
        #   # FYI, this is in the Puma starting process.
        #   puts &quot;#{Thread.current.object_id}&quot; # returns '70144220123860'
        #   handle_servers
        # end
        puts &quot;#{Thread.current.object_id}&quot;
          
        @check.close
        @notify.close

        # ...
      end
    end
    
    def handle_check
      cmd = @check.read(1)

      case cmd
      when STOP_COMMAND
        @status = :stop # The @status is updated to :stop for this example. 
        return true
      when HALT_COMMAND
        @status = :halt
        return true
      when RESTART_COMMAND
        @status = :restart
        return true
      end

      return false
    end
    
    def graceful_shutdown
      if @thread_pool
        @thread_pool.shutdown # Let's step into this line.
      end
    end    
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/launcher.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># Puma::Launcher is the single entry point for starting a Puma server based on user</span>
  <span class="pl-c"># configuration.</span>
  <span class="pl-k">class</span> <span class="pl-v">Launcher</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span>
      <span class="pl-c">#...</span>

      <span class="pl-c"># Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. </span>
      <span class="pl-en">setup_signals</span> <span class="pl-c"># Let's step into this line.</span>
      
      <span class="pl-en">set_process_title</span>
      
      <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">run</span>

      <span class="pl-c"># ...</span>
    <span class="pl-k">end</span>
    
    <span class="pl-c"># Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.</span>
    <span class="pl-c"># Signal.list #=&gt; {"EXIT"=&gt;0, "HUP"=&gt;1, "INT"=&gt;2, "QUIT"=&gt;3, "ILL"=&gt;4, "TRAP"=&gt;5, "IOT"=&gt;6, "ABRT"=&gt;6, "FPE"=&gt;8, "KILL"=&gt;9, "BUS"=&gt;7, "SEGV"=&gt;11, "SYS"=&gt;31, "PIPE"=&gt;13, "ALRM"=&gt;14, "TERM"=&gt;15, "URG"=&gt;23, "STOP"=&gt;19, "TSTP"=&gt;20, "CONT"=&gt;18, "CHLD"=&gt;17, "CLD"=&gt;17, "TTIN"=&gt;21, "TTOU"=&gt;22, "IO"=&gt;29, "XCPU"=&gt;24, "XFSZ"=&gt;25, "VTALRM"=&gt;26, "PROF"=&gt;27, "WINCH"=&gt;28, "USR1"=&gt;10, "USR2"=&gt;12, "PWR"=&gt;30, "POLL"=&gt;29}</span>
    <span class="pl-c"># Press `Control + C` to quit means 'SIGINT'.</span>
    <span class="pl-k">def</span> <span class="pl-en">setup_signals</span>
      <span class="pl-k">begin</span>
        <span class="pl-c"># After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap "SIGTERM"`.</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGTERM"</span> <span class="pl-k">do</span>
          <span class="pl-en">graceful_stop</span> <span class="pl-c"># Let's step into this line.</span>

          <span class="pl-en">raise</span> <span class="pl-v">SignalException</span><span class="pl-kos">,</span> <span class="pl-s">"SIGTERM"</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGTERM not implemented, signal based gracefully stopping unavailable!"</span>
      <span class="pl-k">end</span>
            
      <span class="pl-k">begin</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGUSR2"</span> <span class="pl-k">do</span>
          <span class="pl-en">restart</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGUSR2 not implemented, signal based restart unavailable!"</span>
      <span class="pl-k">end</span>

      <span class="pl-k">begin</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGUSR1"</span> <span class="pl-k">do</span>
          <span class="pl-en">phased_restart</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGUSR1 not implemented, signal based restart unavailable!"</span>
      <span class="pl-k">end</span>

      <span class="pl-k">begin</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGINT"</span> <span class="pl-k">do</span>
          <span class="pl-k">if</span> <span class="pl-v">Puma</span><span class="pl-kos">.</span><span class="pl-en">jruby?</span>
            <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:exit</span>
            <span class="pl-en">graceful_stop</span>
            <span class="pl-en">exit</span>
          <span class="pl-k">end</span>

          <span class="pl-en">stop</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGINT not implemented, signal based gracefully stopping unavailable!"</span>
      <span class="pl-k">end</span>

      <span class="pl-k">begin</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGHUP"</span> <span class="pl-k">do</span>
          <span class="pl-k">if</span> <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">redirected_io?</span>
            <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">redirect_io</span>
          <span class="pl-k">else</span>
            <span class="pl-en">stop</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGHUP not implemented, signal based logs reopening unavailable!"</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">graceful_stop</span>
      <span class="pl-c"># @runner: instance of Puma::Single (for this example)</span>
      <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">stop_blocked</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-en">log</span> <span class="pl-s">"=== puma shutdown: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Time</span><span class="pl-kos">.</span><span class="pl-en">now</span><span class="pl-kos">}</span></span> ==="</span>
      <span class="pl-en">log</span> <span class="pl-s">"- Goodbye!"</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/puma-3.12.0/lib/puma/launcher.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">Single</span> &lt; <span class="pl-v">Runner</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span>
      <span class="pl-c"># ...</span>

      <span class="pl-c"># @server: Puma::Server.new(app, @launcher.events, @options)</span>
      <span class="pl-c1">@server</span> <span class="pl-c1">=</span> <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-en">start_server</span> <span class="pl-c"># Let's step into this line.</span>

      <span class="pl-c"># ...</span>
      <span class="pl-s1">thread</span> <span class="pl-c1">=</span> <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">run</span>
      
      <span class="pl-c"># This line will suspend the main thread execution.</span>
      <span class="pl-c"># And the `thread`'s block (which is the method `handle_servers`) will be executed.  </span>
      <span class="pl-s1">thread</span><span class="pl-kos">.</span><span class="pl-en">join</span>
    <span class="pl-k">end</span>
      
    <span class="pl-k">def</span> <span class="pl-en">stop_blocked</span>
      <span class="pl-en">log</span> <span class="pl-s">"- Gracefully stopping, waiting for requests to finish"</span>
      <span class="pl-c1">@control</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-c1">true</span><span class="pl-kos">)</span> <span class="pl-k">if</span> <span class="pl-c1">@control</span>
      <span class="pl-c"># @server: instance of Puma::Server</span>
      <span class="pl-c1">@server</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-c1">true</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span>

<span class="pl-c"># .gems/puma-3.12.0/lib/puma/server.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">Server</span>
    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">,</span> <span class="pl-s1">events</span><span class="pl-c1">=</span><span class="pl-v">Events</span><span class="pl-kos">.</span><span class="pl-en">stdio</span><span class="pl-kos">,</span> <span class="pl-s1">options</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-c"># 'Puma::Util.pipe' returns `IO.pipe`.</span>
      <span class="pl-c1">@check</span><span class="pl-kos">,</span> <span class="pl-c1">@notify</span> <span class="pl-c1">=</span> <span class="pl-v">Puma</span>::<span class="pl-v">Util</span><span class="pl-kos">.</span><span class="pl-en">pipe</span> <span class="pl-c"># @check, @notify is a pair.</span>

      <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:stop</span>
    <span class="pl-k">end</span>
      
    <span class="pl-k">def</span> <span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-s1">background</span><span class="pl-c1">=</span><span class="pl-c1">true</span><span class="pl-kos">)</span>
      <span class="pl-c"># ...</span>
      <span class="pl-c1">@thread_pool</span> <span class="pl-c1">=</span> <span class="pl-v">ThreadPool</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@min_threads</span><span class="pl-kos">,</span>
                                    <span class="pl-c1">@max_threads</span><span class="pl-kos">,</span>
                                    <span class="pl-v">IOBuffer</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span>|

        <span class="pl-c">#...</span>
        <span class="pl-c"># Process the request.</span>
        <span class="pl-en">process_client</span><span class="pl-kos">(</span><span class="pl-s1">client</span><span class="pl-kos">,</span> <span class="pl-s1">buffer</span><span class="pl-kos">)</span>  
        <span class="pl-c">#...</span>
      <span class="pl-k">end</span>
      
      <span class="pl-c"># 'Thread.current.object_id' returns '70144214949920', </span>
      <span class="pl-c"># which is the same as the 'Thread.current.object_id' in Puma::Server#stop.</span>
      <span class="pl-c"># Current thread is the main thread here.</span>
      <span class="pl-en">puts</span> <span class="pl-s">"<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">object_id</span><span class="pl-kos">}</span></span>"</span>
      
      <span class="pl-c"># The created @thread is the @thread in `stop` method below.</span>
      <span class="pl-c1">@thread</span> <span class="pl-c1">=</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span> <span class="pl-kos">{</span>
        <span class="pl-c"># FYI, this is in the Puma starting process.      </span>
        <span class="pl-c"># 'Thread.current.object_id' returns '70144220123860', </span>
        <span class="pl-c"># which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run</span>
        <span class="pl-c"># def handle_servers</span>
        <span class="pl-c">#   begin</span>
        <span class="pl-c">#     # ...</span>
        <span class="pl-c">#   ensure</span>
        <span class="pl-c">#     # FYI, the 'ensure' part is in the Puma stopping process.</span>
        <span class="pl-c">#     puts "#{Thread.current.object_id}" # returns '70144220123860' too.</span>
        <span class="pl-c">#   end</span>
        <span class="pl-c"># end</span>
        <span class="pl-en">puts</span> <span class="pl-s">"<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">object_id</span><span class="pl-kos">}</span></span>"</span> <span class="pl-c"># returns '70144220123860'</span>
        
        <span class="pl-en">handle_servers</span>
      <span class="pl-kos">}</span>
      <span class="pl-k">return</span> <span class="pl-c1">@thread</span>
    <span class="pl-k">end</span>
      
    <span class="pl-c"># Stops the acceptor thread and then causes the worker threads to finish</span>
    <span class="pl-c"># off the request queue before finally exiting.</span>
    <span class="pl-k">def</span> <span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-s1">sync</span><span class="pl-c1">=</span><span class="pl-c1">false</span><span class="pl-kos">)</span>
      <span class="pl-c"># This line will set '@status = :stop',</span>
      <span class="pl-c"># and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.</span>
      <span class="pl-c"># So that the code after `ios = IO.select sockets` will be executed.   </span>
      <span class="pl-en">notify_safely</span><span class="pl-kos">(</span><span class="pl-c1">STOP_COMMAND</span><span class="pl-kos">)</span> <span class="pl-c"># Let's step into this line.</span>
      
      <span class="pl-c"># 'Thread.current.object_id' returns '70144214949920', </span>
      <span class="pl-c"># which is the same as the 'Thread.current.object_id' in Puma::Server#run.</span>
      <span class="pl-c"># Current thread is exactly the main thread here.</span>
      <span class="pl-en">puts</span> <span class="pl-s">"<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">object_id</span><span class="pl-kos">}</span></span>"</span>
      
      <span class="pl-c"># The @thread is just the always running Thread created in `Puma::Server#run`.</span>
      <span class="pl-c"># Please look at method `Puma::Server#run`.</span>
      <span class="pl-c"># `@thread.join` will suspend the main thread execution.</span>
      <span class="pl-c"># And the code in @thread will continue be executed.</span>
      <span class="pl-c1">@thread</span><span class="pl-kos">.</span><span class="pl-en">join</span> <span class="pl-k">if</span> <span class="pl-c1">@thread</span> &amp;&amp; <span class="pl-s1">sync</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">notify_safely</span><span class="pl-kos">(</span><span class="pl-s1">message</span><span class="pl-kos">)</span>
      <span class="pl-c1">@notify</span> &lt;&lt; <span class="pl-s1">message</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">handle_servers</span>
      <span class="pl-k">begin</span>
        <span class="pl-s1">check</span> <span class="pl-c1">=</span> <span class="pl-c1">@check</span>
        <span class="pl-c"># sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;]</span>
        <span class="pl-s1">sockets</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-s1">check</span><span class="pl-kos">]</span> + <span class="pl-c1">@binder</span><span class="pl-kos">.</span><span class="pl-en">ios</span>
        <span class="pl-s1">pool</span> <span class="pl-c1">=</span> <span class="pl-c1">@thread_pool</span>
        <span class="pl-c">#...</span>
 
        <span class="pl-k">while</span> <span class="pl-c1">@status</span> == <span class="pl-pds">:run</span>
          <span class="pl-c"># After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.</span>
          <span class="pl-c"># FYI, `@check, @notify = IO.pipe`.</span>
          <span class="pl-c"># def notify_safely(message)</span>
          <span class="pl-c">#   @notify &lt;&lt; message</span>
          <span class="pl-c"># end</span>
          <span class="pl-c"># sockets: [#&lt;IO:fd 23&gt;, #&lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&gt;]</span>
          <span class="pl-s1">ios</span> <span class="pl-c1">=</span> <span class="pl-c1">IO</span><span class="pl-kos">.</span><span class="pl-en">select</span> <span class="pl-s1">sockets</span>
            
          <span class="pl-s1">ios</span><span class="pl-kos">.</span><span class="pl-en">first</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">sock</span>|
            <span class="pl-k">if</span> <span class="pl-s1">sock</span> == <span class="pl-s1">check</span>
              <span class="pl-c"># The @status is updated to :stop for this example in `handle_check`.</span>
              <span class="pl-k">break</span> <span class="pl-k">if</span> <span class="pl-en">handle_check</span> <span class="pl-c"># Let's step into this line.</span>
            <span class="pl-k">else</span>
              <span class="pl-k">if</span> <span class="pl-s1">io</span> <span class="pl-c1">=</span> <span class="pl-s1">sock</span><span class="pl-kos">.</span><span class="pl-en">accept_nonblock</span>
                <span class="pl-s1">client</span> <span class="pl-c1">=</span> <span class="pl-v">Client</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s1">io</span><span class="pl-kos">,</span> <span class="pl-c1">@binder</span><span class="pl-kos">.</span><span class="pl-en">env</span><span class="pl-kos">(</span><span class="pl-s1">sock</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
                
                <span class="pl-c"># ...</span>
                <span class="pl-s1">pool</span> &lt;&lt; <span class="pl-s1">client</span>
                <span class="pl-s1">pool</span><span class="pl-kos">.</span><span class="pl-en">wait_until_not_full</span>
              <span class="pl-k">end</span>
            <span class="pl-k">end</span>
          <span class="pl-k">end</span>
        <span class="pl-k">end</span>
        
        <span class="pl-c"># Let's step into `graceful_shutdown`.</span>
        <span class="pl-en">graceful_shutdown</span> <span class="pl-k">if</span> <span class="pl-c1">@status</span> == <span class="pl-pds">:stop</span> || <span class="pl-c1">@status</span> == <span class="pl-pds">:restart</span>
        
      <span class="pl-c"># ...</span>
      <span class="pl-k">ensure</span>
        <span class="pl-c"># FYI, the 'ensure' part is in the Puma stopping process.</span>
        <span class="pl-c"># 'Thread.current.object_id' returns '70144220123860', </span>
        <span class="pl-c"># which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run</span>
        <span class="pl-c"># @thread = Thread.new do</span>
        <span class="pl-c">#   # FYI, this is in the Puma starting process.</span>
        <span class="pl-c">#   puts "#{Thread.current.object_id}" # returns '70144220123860'</span>
        <span class="pl-c">#   handle_servers</span>
        <span class="pl-c"># end</span>
        <span class="pl-en">puts</span> <span class="pl-s">"<span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">current</span><span class="pl-kos">.</span><span class="pl-en">object_id</span><span class="pl-kos">}</span></span>"</span>
          
        <span class="pl-c1">@check</span><span class="pl-kos">.</span><span class="pl-en">close</span>
        <span class="pl-c1">@notify</span><span class="pl-kos">.</span><span class="pl-en">close</span>

        <span class="pl-c"># ...</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">handle_check</span>
      <span class="pl-s1">cmd</span> <span class="pl-c1">=</span> <span class="pl-c1">@check</span><span class="pl-kos">.</span><span class="pl-en">read</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span>

      <span class="pl-k">case</span> <span class="pl-s1">cmd</span>
      <span class="pl-k">when</span> <span class="pl-c1">STOP_COMMAND</span>
        <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:stop</span> <span class="pl-c"># The @status is updated to :stop for this example. </span>
        <span class="pl-k">return</span> <span class="pl-c1">true</span>
      <span class="pl-k">when</span> <span class="pl-c1">HALT_COMMAND</span>
        <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:halt</span>
        <span class="pl-k">return</span> <span class="pl-c1">true</span>
      <span class="pl-k">when</span> <span class="pl-c1">RESTART_COMMAND</span>
        <span class="pl-c1">@status</span> <span class="pl-c1">=</span> <span class="pl-pds">:restart</span>
        <span class="pl-k">return</span> <span class="pl-c1">true</span>
      <span class="pl-k">end</span>

      <span class="pl-k">return</span> <span class="pl-c1">false</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">graceful_shutdown</span>
      <span class="pl-k">if</span> <span class="pl-c1">@thread_pool</span>
        <span class="pl-c1">@thread_pool</span><span class="pl-kos">.</span><span class="pl-en">shutdown</span> <span class="pl-c"># Let's step into this line.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>    
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module Puma
  class ThreadPool
    # Tell all threads in the pool to exit and wait for them to finish.
    def shutdown(timeout=-1)
      threads = @mutex.synchronize do
        @shutdown = true
        # `broadcast` will wakes up all threads waiting for this lock.
        @not_empty.broadcast
        @not_full.broadcast

        # ...
        
        # dup workers so that we join them all safely
        # @workers is an array.   
        # @workers.dup will not create new thread.
        # @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). 
        # So ues @workers.dup here.
        @workers.dup
      end

      # Wait for threads to finish without force shutdown.
      threads.each do |thread|
        thread.join
      end

      @spawned = 0
      @workers = []
    end

    def initialize(min, max, *extra, &amp;block)
      #..
      @mutex = Mutex.new
      @spawned = 0 # The count of @spawned threads.
      @todo = [] # @todo is requests (in Puma, it's Puma::Client instance) which need to be processed.  
      @min = Integer(min) # @min threads count
      @block = block # block will be called in method `spawn_thread` to process a request.    
      @workers = []

      @mutex.synchronize do
        @min.times { spawn_thread } # Puma spawns @min count threads.
      end
    end
    
    def spawn_thread
      @spawned += 1

      # Run a new Thread now.
      # The block of the thread will be executed separately from the calling thread. 
      th = Thread.new(@spawned) do |spawned|
        block = @block
        mutex = @mutex
        #...
 
        while true
          work = nil

          continue = true

          mutex.synchronize do
            while todo.empty?
              # ...
 
              if @shutdown
                continue = false
                break
              end

              # ...
              # After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.
              # Ruby will continue to execute the next line here.
              not_empty.wait mutex
              
              @waiting -= 1
            end

            # ...
          end

          break unless continue

          # ...
        end

        mutex.synchronize do
          @spawned -= 1
          @workers.delete th
        end
      end # end of the Thread.new.

      @workers &lt;&lt; th

      th
    end
  end
end"><pre><span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-k">class</span> <span class="pl-v">ThreadPool</span>
    <span class="pl-c"># Tell all threads in the pool to exit and wait for them to finish.</span>
    <span class="pl-k">def</span> <span class="pl-en">shutdown</span><span class="pl-kos">(</span><span class="pl-s1">timeout</span><span class="pl-c1">=</span>-<span class="pl-c1">1</span><span class="pl-kos">)</span>
      <span class="pl-s1">threads</span> <span class="pl-c1">=</span> <span class="pl-c1">@mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-c1">@shutdown</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>
        <span class="pl-c"># `broadcast` will wakes up all threads waiting for this lock.</span>
        <span class="pl-c1">@not_empty</span><span class="pl-kos">.</span><span class="pl-en">broadcast</span>
        <span class="pl-c1">@not_full</span><span class="pl-kos">.</span><span class="pl-en">broadcast</span>

        <span class="pl-c"># ...</span>
        
        <span class="pl-c"># dup workers so that we join them all safely</span>
        <span class="pl-c"># @workers is an array.   </span>
        <span class="pl-c"># @workers.dup will not create new thread.</span>
        <span class="pl-c"># @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). </span>
        <span class="pl-c"># So ues @workers.dup here.</span>
        <span class="pl-c1">@workers</span><span class="pl-kos">.</span><span class="pl-en">dup</span>
      <span class="pl-k">end</span>

      <span class="pl-c"># Wait for threads to finish without force shutdown.</span>
      <span class="pl-s1">threads</span><span class="pl-kos">.</span><span class="pl-en">each</span> <span class="pl-k">do</span> |<span class="pl-s1">thread</span>|
        <span class="pl-s1">thread</span><span class="pl-kos">.</span><span class="pl-en">join</span>
      <span class="pl-k">end</span>

      <span class="pl-c1">@spawned</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>
      <span class="pl-c1">@workers</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span>
    <span class="pl-k">end</span>

    <span class="pl-k">def</span> <span class="pl-en">initialize</span><span class="pl-kos">(</span><span class="pl-s1">min</span><span class="pl-kos">,</span> <span class="pl-s1">max</span><span class="pl-kos">,</span> *<span class="pl-s1">extra</span><span class="pl-kos">,</span> &amp;<span class="pl-s1">block</span><span class="pl-kos">)</span>
      <span class="pl-c">#..</span>
      <span class="pl-c1">@mutex</span> <span class="pl-c1">=</span> <span class="pl-v">Mutex</span><span class="pl-kos">.</span><span class="pl-en">new</span>
      <span class="pl-c1">@spawned</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span> <span class="pl-c"># The count of @spawned threads.</span>
      <span class="pl-c1">@todo</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c"># @todo is requests (in Puma, it's Puma::Client instance) which need to be processed.  </span>
      <span class="pl-c1">@min</span> <span class="pl-c1">=</span> <span class="pl-en">Integer</span><span class="pl-kos">(</span><span class="pl-s1">min</span><span class="pl-kos">)</span> <span class="pl-c"># @min threads count</span>
      <span class="pl-c1">@block</span> <span class="pl-c1">=</span> <span class="pl-s1">block</span> <span class="pl-c"># block will be called in method `spawn_thread` to process a request.    </span>
      <span class="pl-c1">@workers</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span>

      <span class="pl-c1">@mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
        <span class="pl-c1">@min</span><span class="pl-kos">.</span><span class="pl-en">times</span> <span class="pl-kos">{</span> <span class="pl-en">spawn_thread</span> <span class="pl-kos">}</span> <span class="pl-c"># Puma spawns @min count threads.</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">spawn_thread</span>
      <span class="pl-c1">@spawned</span> += <span class="pl-c1">1</span>

      <span class="pl-c"># Run a new Thread now.</span>
      <span class="pl-c"># The block of the thread will be executed separately from the calling thread. </span>
      <span class="pl-s1">th</span> <span class="pl-c1">=</span> <span class="pl-v">Thread</span><span class="pl-kos">.</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-c1">@spawned</span><span class="pl-kos">)</span> <span class="pl-k">do</span> |<span class="pl-s1">spawned</span>|
        <span class="pl-s1">block</span> <span class="pl-c1">=</span> <span class="pl-c1">@block</span>
        <span class="pl-s1">mutex</span> <span class="pl-c1">=</span> <span class="pl-c1">@mutex</span>
        <span class="pl-c">#...</span>
 
        <span class="pl-k">while</span> <span class="pl-c1">true</span>
          <span class="pl-s1">work</span> <span class="pl-c1">=</span> <span class="pl-c1">nil</span>

          <span class="pl-s1">continue</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span>

          <span class="pl-s1">mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
            <span class="pl-k">while</span> <span class="pl-en">todo</span><span class="pl-kos">.</span><span class="pl-en">empty?</span>
              <span class="pl-c"># ...</span>
 
              <span class="pl-k">if</span> <span class="pl-c1">@shutdown</span>
                <span class="pl-s1">continue</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>
                <span class="pl-k">break</span>
              <span class="pl-k">end</span>

              <span class="pl-c"># ...</span>
              <span class="pl-c"># After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.</span>
              <span class="pl-c"># Ruby will continue to execute the next line here.</span>
              <span class="pl-en">not_empty</span><span class="pl-kos">.</span><span class="pl-en">wait</span> <span class="pl-s1">mutex</span>
              
              <span class="pl-c1">@waiting</span> -= <span class="pl-c1">1</span>
            <span class="pl-k">end</span>

            <span class="pl-c"># ...</span>
          <span class="pl-k">end</span>

          <span class="pl-k">break</span> <span class="pl-k">unless</span> <span class="pl-s1">continue</span>

          <span class="pl-c"># ...</span>
        <span class="pl-k">end</span>

        <span class="pl-s1">mutex</span><span class="pl-kos">.</span><span class="pl-en">synchronize</span> <span class="pl-k">do</span>
          <span class="pl-c1">@spawned</span> -= <span class="pl-c1">1</span>
          <span class="pl-c1">@workers</span><span class="pl-kos">.</span><span class="pl-en">delete</span> <span class="pl-s1">th</span>
        <span class="pl-k">end</span>
      <span class="pl-k">end</span> <span class="pl-c"># end of the Thread.new.</span>

      <span class="pl-c1">@workers</span> &lt;&lt; <span class="pl-s1">th</span>

      <span class="pl-s1">th</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">So all the threads in the ThreadPool joined and finished.</p>
<p dir="auto">Let's inspect the caller in block of <code>Signal.trap "SIGTERM"</code> below.</p>
<div class="highlight highlight-source-ruby notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# .gems/puma-3.12.0/lib/puma/launcher.rb
module Puma
  # Puma::Launcher is the single entry point for starting a Puma server based on user
  # configuration.
  class Launcher
    def run
      #...

      # Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. 
      setup_signals # Let's step into this line.
      
      set_process_title
      
      # Process.pid: 42264 
      puts &quot;Process.pid: #{Process.pid}&quot;
      
      @runner.run

      # ...
    end
    
    def setup_signals
      # ...
      begin
        # After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap &quot;SIGTERM&quot;`.
        Signal.trap &quot;SIGTERM&quot; do
          # I inspect `caller` to see the caller stack.
          # caller: [
          #   &quot;../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'&quot;, 
          #   &quot;../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'&quot;,
          #   &quot;../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'&quot;,
          #   &quot;../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'&quot;,
          #   &quot;../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'&quot;,
          #   &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'&quot;, 
          #   &quot;../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'&quot;, 
          #   &quot;../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'&quot;, 
          #   &quot;../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'&quot;, 
          #   &quot;../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&lt;top (required)&gt;'&quot;, 
          #   &quot;../path/to/your_project/bin/rails:5:in `require'&quot;, 
          #   &quot;../path/to/your_project/bin/rails:5:in `&lt;main&gt;'&quot;
          # ]
          puts &quot;caller: #{caller.inspect}&quot;
          
          # Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.
          puts &quot;Process.pid: #{Process.pid}&quot;
          
          graceful_stop
          
          # This SignalException is not rescued in the caller stack.
          # So in the the caller stack, Ruby will goto the `ensure` part in
          # &quot;../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'&quot;.
          # So the last code executed is `puts &quot;Exiting&quot; unless @options &amp;&amp; options[:daemonize]`
          # when running `$ kill -s SIGTERM puma_process_id`.
          # You can search `puts &quot;Exiting&quot;` in this document to see it.
          raise SignalException, &quot;SIGTERM&quot;
        end
      rescue Exception
        # This `rescue` is only for `Signal.trap &quot;SIGTERM&quot;`, not for `raise SignalException, &quot;SIGTERM&quot;`.
        log &quot;*** SIGTERM not implemented, signal based gracefully stopping unavailable!&quot;
      end
    end
  end
end"><pre><span class="pl-c"># .gems/puma-3.12.0/lib/puma/launcher.rb</span>
<span class="pl-k">module</span> <span class="pl-v">Puma</span>
  <span class="pl-c"># Puma::Launcher is the single entry point for starting a Puma server based on user</span>
  <span class="pl-c"># configuration.</span>
  <span class="pl-k">class</span> <span class="pl-v">Launcher</span>
    <span class="pl-k">def</span> <span class="pl-en">run</span>
      <span class="pl-c">#...</span>

      <span class="pl-c"># Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. </span>
      <span class="pl-en">setup_signals</span> <span class="pl-c"># Let's step into this line.</span>
      
      <span class="pl-en">set_process_title</span>
      
      <span class="pl-c"># Process.pid: 42264 </span>
      <span class="pl-en">puts</span> <span class="pl-s">"Process.pid: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Process</span><span class="pl-kos">.</span><span class="pl-en">pid</span><span class="pl-kos">}</span></span>"</span>
      
      <span class="pl-c1">@runner</span><span class="pl-kos">.</span><span class="pl-en">run</span>

      <span class="pl-c"># ...</span>
    <span class="pl-k">end</span>
    
    <span class="pl-k">def</span> <span class="pl-en">setup_signals</span>
      <span class="pl-c"># ...</span>
      <span class="pl-k">begin</span>
        <span class="pl-c"># After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap "SIGTERM"`.</span>
        <span class="pl-v">Signal</span><span class="pl-kos">.</span><span class="pl-en">trap</span> <span class="pl-s">"SIGTERM"</span> <span class="pl-k">do</span>
          <span class="pl-c"># I inspect `caller` to see the caller stack.</span>
          <span class="pl-c"># caller: [</span>
          <span class="pl-c">#   "../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'", </span>
          <span class="pl-c">#   "../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'",</span>
          <span class="pl-c">#   "../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'",</span>
          <span class="pl-c">#   "../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'",</span>
          <span class="pl-c">#   "../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'",</span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'", </span>
          <span class="pl-c">#   "../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'", </span>
          <span class="pl-c">#   "../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'", </span>
          <span class="pl-c">#   "../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'", </span>
          <span class="pl-c">#   "../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&lt;top (required)&gt;'", </span>
          <span class="pl-c">#   "../path/to/your_project/bin/rails:5:in `require'", </span>
          <span class="pl-c">#   "../path/to/your_project/bin/rails:5:in `&lt;main&gt;'"</span>
          <span class="pl-c"># ]</span>
          <span class="pl-en">puts</span> <span class="pl-s">"caller: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-en">caller</span><span class="pl-kos">.</span><span class="pl-en">inspect</span><span class="pl-kos">}</span></span>"</span>
          
          <span class="pl-c"># Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.</span>
          <span class="pl-en">puts</span> <span class="pl-s">"Process.pid: <span class="pl-s1"><span class="pl-kos">#{</span><span class="pl-v">Process</span><span class="pl-kos">.</span><span class="pl-en">pid</span><span class="pl-kos">}</span></span>"</span>
          
          <span class="pl-en">graceful_stop</span>
          
          <span class="pl-c"># This SignalException is not rescued in the caller stack.</span>
          <span class="pl-c"># So in the the caller stack, Ruby will goto the `ensure` part in</span>
          <span class="pl-c"># "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'".</span>
          <span class="pl-c"># So the last code executed is `puts "Exiting" unless @options &amp;&amp; options[:daemonize]`</span>
          <span class="pl-c"># when running `$ kill -s SIGTERM puma_process_id`.</span>
          <span class="pl-c"># You can search `puts "Exiting"` in this document to see it.</span>
          <span class="pl-en">raise</span> <span class="pl-v">SignalException</span><span class="pl-kos">,</span> <span class="pl-s">"SIGTERM"</span>
        <span class="pl-k">end</span>
      <span class="pl-k">rescue</span> <span class="pl-v">Exception</span>
        <span class="pl-c"># This `rescue` is only for `Signal.trap "SIGTERM"`, not for `raise SignalException, "SIGTERM"`.</span>
        <span class="pl-en">log</span> <span class="pl-s">"*** SIGTERM not implemented, signal based gracefully stopping unavailable!"</span>
      <span class="pl-k">end</span>
    <span class="pl-k">end</span>
  <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">Welcome to point out the mistakes in this article :)</p>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

