diff --git a/404.html b/404.html index 12ca92f63ce..66d529e49f2 100644 --- a/404.html +++ b/404.html @@ -4,8 +4,8 @@ Page Not Found | Apache YuniKorn - - + +
@@ -16,7 +16,7 @@

The Apache Software Foundation Apache YuniKorn, YuniKorn, Apache, the Apache feather, and the Apache YuniKorn project logo are either registered trademarks or trademarks of the Apache Software Foundation.

- - + + \ No newline at end of file diff --git a/assets/images/application-state-43c26f8a6a803d863e8ef73311f786eb.png b/assets/images/application-state-43c26f8a6a803d863e8ef73311f786eb.png new file mode 100644 index 00000000000..ec1b365b954 Binary files /dev/null and b/assets/images/application-state-43c26f8a6a803d863e8ef73311f786eb.png differ diff --git a/assets/js/073760cf.4c6da827.js b/assets/js/073760cf.4c6da827.js deleted file mode 100644 index 2b7ea34106c..00000000000 --- a/assets/js/073760cf.4c6da827.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[60043],{58860:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>y});var a=n(37953);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=a.createContext({}),g=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=g(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=g(n),m=l,y=d["".concat(s,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(y,i(i({ref:t},p),{},{components:n})):a.createElement(y,i({ref:t},p))}));function y(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=n.length,i=new Array(r);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:l,i[1]=o;for(var g=2;g{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>g});var a=n(72994),l=(n(37953),n(58860));const r={id:"historical_usage_tracking",title:"Historical Usage Tracking"},i=void 0,o={unversionedId:"design/historical_usage_tracking",id:"design/historical_usage_tracking",title:"Historical Usage Tracking",description:"\x3c!--",source:"@site/docs/design/historical_usage_tracking.md",sourceDirName:"design",slug:"/design/historical_usage_tracking",permalink:"/docs/next/design/historical_usage_tracking",draft:!1,tags:[],version:"current",frontMatter:{id:"historical_usage_tracking",title:"Historical Usage Tracking"},sidebar:"docs",previous:{title:"User Based Quota Enforcement",permalink:"/docs/next/design/user_group_resource_usage_enforcement"},next:{title:"Simplifying Interface Messages",permalink:"/docs/next/design/interface_message_simplification"}},s={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:2},{value:"Non Goals",id:"non-goals",level:2},{value:"Existing Event System",id:"existing-event-system",level:2},{value:"Scheduler integration",id:"scheduler-integration",level:3},{value:"Event storage",id:"event-storage",level:3},{value:"Publishing events",id:"publishing-events",level:3},{value:"Event System Updates",id:"event-system-updates",level:2},{value:"Event description",id:"event-description",level:3},{value:"Event types",id:"event-types",level:3},{value:"Change types",id:"change-types",level:3},{value:"Change details",id:"change-details",level:3},{value:"Content definition",id:"content-definition",level:3},{value:"Event storage",id:"event-storage-1",level:2},{value:"Publishing events",id:"publishing-events-1",level:3},{value:"SHIM events",id:"shim-events",level:4},{value:"REST",id:"rest",level:4},{value:"Streaming",id:"streaming",level:4},{value:"Event overview",id:"event-overview",level:2},{value:"Generic events",id:"generic-events",level:3},{value:"Shim events",id:"shim-events-1",level:3},{value:"Configuration",id:"configuration",level:2},{value:"Performance considerations",id:"performance-considerations",level:2},{value:"Memory usage of historical elements",id:"memory-usage-of-historical-elements",level:3},{value:"Handling slow and rogue clients during streaming",id:"handling-slow-and-rogue-clients-during-streaming",level:3},{value:"Approaches to streaming",id:"approaches-to-streaming",level:3},{value:"Send history first, then stream new events",id:"send-history-first-then-stream-new-events",level:4},{value:"Stream new events directly from ring buffer",id:"stream-new-events-directly-from-ring-buffer",level:4}],p={toc:g},d="wrapper";function u(e){let{components:t,...n}=e;return(0,l.yg)(d,(0,a.A)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,l.yg)("h2",{id:"introduction"},"Introduction"),(0,l.yg)("p",null,"Tracking an application lifecycle is not easy in the current YuniKorn setup.\nLogs and statedump data is required to build an overview.\nHistorical tracking of applications is only possible with limited detail per application.\nApplications come and go, we only track what is running and a time limited set of completed applications."),(0,l.yg)("p",null,"Storing detailed tracking information in memory is problematic.\nUnbound growth can cause performance issues or even an out of memory failure of the service.\nThe lessons learned from the YARN days have shown that it is not simple."),(0,l.yg)("p",null,"A conscious choice was also made to keep YuniKorn stateless.\nThe service does not maintain its own datastore for any of its operations.\nAdding a datastore for application and usage tracking will complicate things."),(0,l.yg)("p",null,"Tracking data can be easily generated and made available for external consumption.\nThe design will discuss the option to generate an event stream for applications, queues and nodes to allow external tools to build an overview of the usage pattern."),(0,l.yg)("p",null,"Work to be tracked under ",(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-1628"},"YUNIKORN-1628")),(0,l.yg)("h2",{id:"goals"},"Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for an application, including: ",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Asks and allocation changes"))),(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for a node, including:",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Allocation changes"))),(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for a queue, including:",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Usage changes"))),(0,l.yg)("li",{parentName:"ul"},"Define a REST interface for event retrieval")),(0,l.yg)("h2",{id:"non-goals"},"Non Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Add a data store for the historical data"),(0,l.yg)("li",{parentName:"ul"},"Display the event information"),(0,l.yg)("li",{parentName:"ul"},"Rebuild data on recovery",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Historical data will not be rebuild"))),(0,l.yg)("li",{parentName:"ul"},"Authentication and Authorisation on the REST interface")),(0,l.yg)("h2",{id:"existing-event-system"},"Existing Event System"),(0,l.yg)("p",null,"The event system was designed to be far more flexible than the current usage.\nEvents for requests, applications, nodes and queues have been defined.\nMost of those are currently not used.\nThe current event system is built on top of a generic event definition.\nThe scheduler interface defines the event as:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"si.EventRecord {\n Type: recordType,\n ObjectID: String,\n GroupID: String,\n Reason: String,\n Message: String,\n TimestampNano: int64,\n}\n")),(0,l.yg)("p",null,"Events definitions are used in the core and shim.\nThe simplicity of the events will most likely not match the current requirements."),(0,l.yg)("p",null,"As part of the standard scheduling cycle we track details at different levels.\nPrometheus' metrics are tracked for specific changes and updates.\nWe also generate events, REQUEST events, that get passed back into the K8shim to attach to the Kubernetes pods."),(0,l.yg)("p",null,"The current events that get passed back are for:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("em",{parentName:"li"},"Insufficient Queue Resources"),": part of the allocation cycle. Called from: ",(0,l.yg)("inlineCode",{parentName:"li"},"Application.tryAllocate()")),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("em",{parentName:"li"},"Placeholder Size Mismatch"),": part of the placeholder replacement cycle. Called from: ",(0,l.yg)("inlineCode",{parentName:"li"},"Application.tryPlaceholderAllocate()"))),(0,l.yg)("p",null,"Both events are of the type REQUEST.\nThe K8shim also implements processing of NODE events but there is no code that generates those types of events.\nThe APPLICATION and QUEUE type events are not created or processed."),(0,l.yg)("p",null,"The event system was added as part of ",(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-42"},"YUNIKORN-42"),".\nThe jira contains a simple design document for the event system.\nIt only was implemented for events that we could not at that point get in any other way: ",(0,l.yg)("a",{parentName:"p",href:"https://docs.google.com/document/d/1aKfY6wnBPCyBl03UfmMHbTSpabAbfxtsHT2KzOgEOQs/edit"},"design v2"),".\nThe original thought was a more generic event system.\nIt would relate everything back to either a pod or the YuniKorn CRD and was focussed on diagnostics and troubleshooting in general: ",(0,l.yg)("a",{parentName:"p",href:"https://docs.google.com/document/d/19iMkLJGVwTSq9OfV9p75wOobJXAxR_CRo4YzSRG_Pzw/edit#heading=h.worp3vfnqgtn"},"design v1"),".\nLinking it all back to a specific pod is The YuniKorn CRD is not used at this point in time."),(0,l.yg)("h3",{id:"scheduler-integration"},"Scheduler integration"),(0,l.yg)("p",null,"When the event system was designed the whole purpose was to allow out of band processing of the events from the scheduling cycle.\nThe events are generated during the scheduling cycle and processed asynchronously in the event system."),(0,l.yg)("p",null,"A channel is used for collecting the events during the scheduling cycle.\nThe scheduler generates an event and adds it for processing to the channel.\nAfter the placement of the event on the channel the scheduler proceeds with the normal cycle.\nProcessing of the events does not, and must not, block the scheduling cycle."),(0,l.yg)("p",null,"This part of the event system must be maintained as it will guarantee the performance of the scheduler."),(0,l.yg)("h3",{id:"event-storage"},"Event storage"),(0,l.yg)("p",null,"All events that have been sent to the channel are read from the channel and placed in a temporary store for publishing.\nThe store is a simple map with the key of the ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),"."),(0,l.yg)("p",null,"Some of the assumptions in the event store however make it not directly usable for the purpose as described here.\nThe main limitation is that there can only be one event in the channel per ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),".\nThe newest one is kept, the older one is dropped when a new event comes in.\nThis however does not mean the code already available with minor changes could be re-used for this purpose."),(0,l.yg)("h3",{id:"publishing-events"},"Publishing events"),(0,l.yg)("p",null,"The current event system uses a push system for event publishing.\nThe event system allows the creation of multiple event publishers.\nThere is no implementation or design for a pull system, like for instance a REST based interface."),(0,l.yg)("p",null,"Currently, there is only an event publisher for a shim defined.\nThis push system will send all the events that have been collected during the push interval to the shim.\nAll events that are pushed will be removed from the store.\nThis keeps the size of the store to a minimum."),(0,l.yg)("p",null,"There is no filtering or post-processing of events implemented.\nEach event stored in the store is forwarded to the shim when the publisher runs.\nSee limitations of the store mentioned above.\nIn the earlier design a level filter was described.\nThat level was never part of the follow-up design, not in the events and not in the processing."),(0,l.yg)("h2",{id:"event-system-updates"},"Event System Updates"),(0,l.yg)("p",null,"The currently defined events are not a fit for the system we want and need.\nSince the events are only used between the core and the K8shim via the publisher we do not need to maintain backwards compatibility.\nChanges can be made to the messages as we do not currently expose the message to the outside."),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"message")," and ",(0,l.yg)("em",{parentName:"p"},"reason")," fields are currently not properly used.\nThe content of the two overlaps.\nThe message in both cases contains the reason, in slightly different wording.\nWe do not need both."),(0,l.yg)("h3",{id:"event-description"},"Event description"),(0,l.yg)("p",null,"We are also missing two fields to allow an extended usage for historical tracking: the ",(0,l.yg)("em",{parentName:"p"},"resource")," and the ",(0,l.yg)("em",{parentName:"p"},"change type"),".\nBased on that the new message that would allow using the event system for tracking historical change would be:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"si.EventRecord {\n Type: eventRecordType,\n ChangeType: eventChangeType,\n ChangeDetail: eventChangeDetail,\n TimestampNano: int64,\n ObjectID: String,\n ReferenceID: String,\n Resource: si.Resource,\n Message: String,\n}\n")),(0,l.yg)("p",null,"The existing ",(0,l.yg)("em",{parentName:"p"},"GroupID")," has been renamed to ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),". The\n",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is the identification of the second object for the event.\nAs an example that would be the Allocation UUID for a new allocation\nadded to an application, request or node. For the queue that would be\nthe application ID."),(0,l.yg)("p",null,"Note that the order of the attributes in the final definition might be\ndifferent as we do not reuse names and IDs in the messages."),(0,l.yg)("h3",{id:"event-types"},"Event types"),(0,l.yg)("p",null,"By keeping the event type for REQUESTS we can still fulfil the original\ndesign of YUNIKORN-42. The current enumeration for the ",(0,l.yg)("em",{parentName:"p"},"eventRecordType"),"\nwould not change. Definition of the eventRecordType enumeration:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"UNKNOWN = 0\nREQUEST = 1\nAPP = 2\nNODE = 3\nQUEUE = 4\n")),(0,l.yg)("h3",{id:"change-types"},"Change types"),(0,l.yg)("p",null,"The additional change type that is added allows us to track the type of\nchange. Depending on the content of the other fields it provides the\npossibility to track all changes we need to track. Definition of the\neventChangeType enumeration:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"NONE = 0\nSET = 1\nADD = 2\nREMOVE = 3\n")),(0,l.yg)("h3",{id:"change-details"},"Change details"),(0,l.yg)("p",null,"Change detail provides more on the reason for the event. The change\ndetail is an enumerated value linked to the event types."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"DETAILS_NONE = 0\n\nREQUEST_CANCEL = 100 // Request cancelled by the RM\nREQUEST_ALLOC = 101 // Request allocated\nREQUEST_TIMEOUT = 102 // Request cancelled due to timeout\n\nAPP_ALLOC = 200 // Allocation changed\nAPP_REQUEST = 201 // Request changed\nAPP_REJECT = 202 // Application rejected on create\nAPP_NEW = 203 // Application added with state new\nAPP_ACCEPTED = 204 // State change to accepted\nAPP_STARTING = 205 // State change to starting\nAPP_RUNNING = 206 // State change to running\nAPP_COMPLETING = 207 // State change to completing\nAPP_COMPLETED = 208 // State change to completed\nAPP_FAILING = 209 // State change to failing\nAPP_FAILED = 210 // State change to failed\nAPP_RESUMING = 211; // State change to resuming\nAPP_EXPIRED = 212; // State change to expired\n\nNODE_DECOMISSION = 300 // Node removal\nNODE_READY = 301 // Node ready state change\nNODE_SCHEDULABLE = 302 // Node schedulable state change (cordon)\nNODE_ALLOC = 303 // Allocation changed\nNODE_CAPACITY = 304 // Capacity changed\nNODE_OCCUPIED = 305 // Occupied resource changed\nNODE_RESERVATION = 306; // Reservation/unreservation occurred\n\nQUEUE_CONFIG = 400 // Managed queue update or removal\nQUEUE_DYNAMIC = 401 // Dynamic queue update or removal\nQUEUE_TYPE = 402 // Queue type change\nQUEUE_MAX = 403 // Max resource changed\nQUEUE_GUARANTEED = 404 // Guaranteed resource changed\nQUEUE_APP = 405 // Application changed\nQUEUE_ALLOC = 406 // Allocation changed\nALLOC_CANCEL = 500 // Allocation cancelled by the RM\nALLOC_PREEMPT = 501 // Allocation preempted by the core\nALLOC_TIMEOUT = 502 // Allocation cancelled due to timeout\nALLOC_REPLACED = 503 // Allocation replacement (placeholder)\nALLOC_NODEREMOVED = 504 // Allocation cancelled, node removal\n")),(0,l.yg)("h3",{id:"content-definition"},"Content definition"),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"eventRecordType")," defines the object that the ",(0,l.yg)("em",{parentName:"p"},"ObjectID")," points to.\nThe content of the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," depends on two things:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Change type"),(0,l.yg)("li",{parentName:"ul"},"Object type inferred by the ",(0,l.yg)("em",{parentName:"li"},"eventRecordType"))),(0,l.yg)("p",null,"For an object of type application it would not make sense to have the reference point to another application etc.\nAt this point the following mapping for ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is assumed:"),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event Type"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference ID"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"Allocation UUID or Request UUID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"Allocation UUID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID or Allocation UUID")))),(0,l.yg)("p",null,"If the ",(0,l.yg)("em",{parentName:"p"},"eventChangeType")," Is NONE or SET the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is always empty.\nThe exception is for the REQUEST as in that case the change type NONE has an application ID set.\nThis special case is used to implement the existing functionality of the event system: sending events to the shim."),(0,l.yg)("p",null,"The APP record type supports Request IDs and Allocation UUIDs to be set in the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),".\nThe type of ID that is referenced is defined by the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail"),"."),(0,l.yg)("p",null,"The QUEUE record type supports application IDs and Allocation UUIDs to be set in the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),".\nIndividual allocations are not tracked on the queue.\nHowever, we leave that option open for the event system at this point."),(0,l.yg)("p",null,"For the QUEUE if ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," and ",(0,l.yg)("em",{parentName:"p"},"Resource")," are set, the ID points to an allocation.\nThis can only happen if the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail")," is set to QUEUE_ALLOC."),(0,l.yg)("p",null,"If only the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is set it points to an application.\nThis can only happen if the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail")," is set to QUEUE_APP.\nBoth cases can use the same ",(0,l.yg)("em",{parentName:"p"},"eventChangeType"),", add or remove an allocation or an application from a queue."),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"Resource")," that is part of any event would be the size of the resource for that change.\nThe interpretation depends on the ",(0,l.yg)("em",{parentName:"p"},"eventChangeType"),".\nFor a SET it is the absolute value. For the ADD and REMOVE it is the positive delta on the existing tracked value.\nThe ",(0,l.yg)("em",{parentName:"p"},"Resource")," is always a positive value."),(0,l.yg)("h2",{id:"event-storage-1"},"Event storage"),(0,l.yg)("p",null,"The storage of events needs to be updated to allow multiple events to be stored for an ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),".\nThis is required as one object could trigger multiple events in a short time and all are important to track.\nThis will require a change from a map based storage to a different store or a change in the key used for the map."),(0,l.yg)("p",null,"The simplest solution might be a slice of pointers to events.\nThe slice has a configurable, limited set of entries.\nThe slice is accessed and maintained as a ring buffer.\nThis will prevent an unlimited growth of the schedulers memory requirements.\nDuring the implementation a decision will be made which configuration, time; count or both, for limiting the size will be supported."),(0,l.yg)("p",null,"Nil, or empty, events will not be added to the storage.\nHowever, no publisher must assume that while processing events retrieved from the buffer and needs to handle nil references.\nA location in the buffer could contain a nil pointer and must be skipped while iterating over the buffer.\nIf a publisher gets a nil event pointer it must not crash and proceed as normal."),(0,l.yg)("p",null,"The current design will use two stores: one for external retrieval and one for the shim events.\nA filter at the receiving end will be created.\nThe shim events will then be processed as per the existing implementation.\nThe new events will be stored and managed as per this design document in ",(0,l.yg)("a",{parentName:"p",href:"#shim-events"},"SHIM events"),"."),(0,l.yg)("h3",{id:"publishing-events-1"},"Publishing events"),(0,l.yg)("p",null,"Events are currently not post processed and all events are sent to the shim.\nWith the newly added events the publishing needs to be split into two separate loops."),(0,l.yg)("h4",{id:"shim-events"},"SHIM events"),(0,l.yg)("p",null,"Current functionality will be supported as described above.\nUpdates are required as the content of the events has changed.\nThe same event type will be generated.\nThe same processing mechanism will be used."),(0,l.yg)("p",null,"As part of processing events REQUEST type events are special.\nThe REQUEST type with the change type NONE has an application ID set and is only sent as an event to the shim.\nThese events must not be made available by any other publishers and are stored in a separate ring buffer.\nAfter the event is sent to the shim the reference to the event in the buffer is cleared, replaced with a nil."),(0,l.yg)("h4",{id:"rest"},"REST"),(0,l.yg)("p",null,"The REST service that is currently running can be reused for exposing the events.\nProposal is to add a new endpoint to the HTTP service.\nThe REST endpoint servicing the event data should be a new end point."),(0,l.yg)("p",null,"Based on the current REST api definition the data exposed in the following new endpoint will be added to expose the events:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/batch\n")),(0,l.yg)("p",null,"The design will not define a sophisticated interface for querying events, like filtering, grouping, etc.\nThis is a deliberate decision.\nSuch an API can encourage bad practices later on.\nThat should be done in a separate application which fetches the events from YuniKorn and persists them in a permanent storage and offers a more feature rich REST/query interface.\nThis would be similar to what already exists in Apache Hadoop like Job History Server or Application Timeline Service."),(0,l.yg)("p",null,"As mentioned earlier in this document, such an application is not in the scope."),(0,l.yg)("p",null,"The batch endpoint, by default, returns a limited number of events.\nThe number of events to return can be specifically set via the query parameter ",(0,l.yg)("em",{parentName:"p"},"count"),".\nIf the requested ",(0,l.yg)("em",{parentName:"p"},"count")," is larger than the available number of events all events are returned."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/batch?count=100\n")),(0,l.yg)("p",null,"To prevent a DOS attack the maximum value of ",(0,l.yg)("em",{parentName:"p"},"count")," might be limited as part of the implementation."),(0,l.yg)("p",null,"The second query parameter that will be supported is ",(0,l.yg)("em",{parentName:"p"},"start"),".\nThis specifies the start ID of the first event returned.\nEvery event is assigned a unique id starting from 0.\nThe ring buffer maintains the current available highest and lowest ID.\nIf ",(0,l.yg)("em",{parentName:"p"},"start")," refers to an ID which doesn't exist in the buffer, then an empty response is returned from the server, with ",(0,l.yg)("em",{parentName:"p"},"LowestID")," and ",(0,l.yg)("em",{parentName:"p"},"HighestID")," properly filled:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-json",metastring:"lines",lines:!0},'{\n "InstanceUUID": "b4751b7d-a1a3-4431-bb68-bff896adb9c2",\n "LowestID": 1100,\n "HighestID": 11000,\n "EventRecords": null\n}\n')),(0,l.yg)("p",null,"In the next request, start should be defined as 1100."),(0,l.yg)("p",null,"In the response, the ",(0,l.yg)("em",{parentName:"p"},"InstanceUUID")," field shows the unique instance ID.\nSince YuniKorn is stateless, the generated ID for an event is not saved anywhere.\nIf an event consumer saves the events to a backend database, it makes it possible to distinguish between events with the same ID.\nAlso, clients can easily detect that YuniKorn was restarted."),(0,l.yg)("h4",{id:"streaming"},"Streaming"),(0,l.yg)("p",null,'Streaming allows the user to see a continuous stream of events as they are occurring.\nThis can be very useful if we want to trace the state changes inside YuniKorn for a longer amount of time.\nThe REST interface can return the last "n" amount of events that occurred in a certain timeframe, but it will always be limited.\nWe can only increase the number of events at the expense of memory usage, which might not be acceptable in certain environments.'),(0,l.yg)("p",null,'Although streaming is a nice feature, we do not consider it as a "must have", at least not in the first version of the history tracking.\nThis is because it\'s more complicated in nature: it maintains an open HTTP connection towards the client which makes it stateful.\nThere are ordering and memory usage concerns&considerations.\nWe need to make sure that rogue clients cannot abuse it.\nTherefore, the first release of history tracking focuses on the batch interface.'),(0,l.yg)("p",null,"Streaming needs to coexist beside the current REST api.\nA separate endpoint must be exposed for the event stream:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/stream\n")),(0,l.yg)("p",null,"Streaming can be similar to how it's implemented inside Kubernetes informers.\nThe API server keeps the connection alive and sends the necessary events about pods, nodes, configmaps, etc.\nThe incoming data stream is decoded by the listeners.\nEvent processing on the client side is not part of this design."),(0,l.yg)("p",null,"At this point we do not provide endpoints for consumers to stream a specific event type as defined in ",(0,l.yg)("a",{parentName:"p",href:"#event-types"},"Event types"),".\nThis could be made available via separate endpoints in the future following the same design as for ",(0,l.yg)("em",{parentName:"p"},"batch")," specification"),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"stream")," endpoint does not take any query parameters.\nThe consumer must allow for more than one (1) event to be sent in one response.\nNo information besides the events will be sent in the response."),(0,l.yg)("p",null,"As an example below the approximate output for the stream endpoint for two events"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "type": 2,\n "changeType": 1,\n "changeDetail": 203,\n "timestamp": 1649167576110750000,\n "objectID": "spark-app-1"\n },\n {\n "type": 4,\n "changeType": 2,\n "changeDetail": 405,\n "timestamp": 1649167576110754000,\n "objectID": "root.spark",\n "referenceID": "spark-app-1"\n }\n]\n')),(0,l.yg)("h2",{id:"event-overview"},"Event overview"),(0,l.yg)("h3",{id:"generic-events"},"Generic events"),(0,l.yg)("p",null,"The following events are generated for streaming and REST consumers, meaning that they will not be sent to the shim.\nThis is based on the description of the ",(0,l.yg)("a",{parentName:"p",href:"#event-system-updates"},"Event System Updates")," earlier in this document.\nIt serves as a reference for the core scheduler actions that will trigger the event."),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change details"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference type"),(0,l.yg)("th",{parentName:"tr",align:null},"Notes"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"New application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Incoming resource request (pod)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal of application")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REJECT"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Application rejected")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_CANCEL"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_TIMEOUT"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Timeout")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_REPLACED"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Replacement (placeholder)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_PREEMPT"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Preemption triggered")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_NODEREMOVED"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Removal triggered by node removal")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST_TIMEOUT"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Timeout (placeholder)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST_CANCEL"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Removal triggered by application removal")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_NEW"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: New")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_ACCEPTED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Accepted")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_STARTING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Starting")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_RUNNING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Running")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_COMPLETING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Completing")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_COMPLETED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Completed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_FAILING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Failing")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_FAILED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Failed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_RESUMING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Resuming")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_EXPIRED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Expired")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null})),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"New node added to the cluster")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_DECOMISSION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal allocation removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_READY"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},'Update "ready" status')),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_SCHEDULABLE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},'Update "schedulable" status')),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_CAPACITY"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Update node capacity")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_OCCUPIED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Update occupied resources")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_RESERVATION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Add reservation to a node")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_RESERVATION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Remove reservation from a node")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null})),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Adding new configured queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_DYNAMIC"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Adding new dynamic queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removing configured queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_DYNAMIC"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removing dynamic queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Application removed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_MAX"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Max resource changed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_GUARANTEED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Guaranteed resource changed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_TYPE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Queue type change(parent/leaf)")))),(0,l.yg)("h3",{id:"shim-events-1"},"Shim events"),(0,l.yg)("p",null,"Shim events are a type of REQUEST and the application ID is set.\nRight now we send only two types of events to the shim, both of which are originated from the application:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Insufficient resources in the queue for a request"),(0,l.yg)("li",{parentName:"ul"},"Real allocation is larger than placeholder")),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change details"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference type"),(0,l.yg)("th",{parentName:"tr",align:null},"Notes"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"New application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")))),(0,l.yg)("h2",{id:"configuration"},"Configuration"),(0,l.yg)("p",null,"As part of the design we anticipate the following configuration to be added for the event storage and retrieval.\nAll settings will have the shared prefix: ",(0,l.yg)("em",{parentName:"p"},"service.event"),".\nAll the mentioned settings will require a restart of the scheduler for updates to take effect."),(0,l.yg)("p",null,"The following settings will be added to the system:"),(0,l.yg)("p",null,"A flag to enable or disable sending request events to the K8shim.\nThis externalises the current setting that needs a recompile of the code.\nThe default mirrors the current default in the code."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"requestEventsEnabled")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: all boolean values will be converted into a boolean using ParseBool as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package",(0,l.yg)("sup",{parentName:"li",id:"fnref-1"},(0,l.yg)("a",{parentName:"sup",href:"#fn-1",className:"footnote-ref"},"1")),"."),(0,l.yg)("li",{parentName:"ul"},"Default value: false")),(0,l.yg)("p",null,"A flag to enable or disable event collection in the system.\nThe default is enabled for the tracking events."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"trackingEventsEnabled")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: all boolean values will be converted into a boolean using ParseBool as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package."),(0,l.yg)("li",{parentName:"ul"},"Default value: true")),(0,l.yg)("p",null,"Size of the store for events that will be sent to the shim, request events.\nNote that setting a size of 0 effectively turns off the request event system."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"requestStoreCapacity")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package",(0,l.yg)("sup",{parentName:"li",id:"fnref-2"},(0,l.yg)("a",{parentName:"sup",href:"#fn-2",className:"footnote-ref"},"2")),"."),(0,l.yg)("li",{parentName:"ul"},"Default value: 1,000")),(0,l.yg)("p",null,"The number of events to store in the ring buffer.\nThis number defines the size of the ring buffer and thus the memory impact the event storage will have on the scheduler.\nNote that setting a size of 0 effectively turns off the event collection system."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"ringBufferCapacity")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package"),(0,l.yg)("li",{parentName:"ul"},"Default value: 100,000")),(0,l.yg)("p",null,"The maximum number of events to return in one REST response.\nThe maximum that could be returned is limited to the ring buffer capacity.\nHowever, preparing a large response the size of the whole ring buffer could cause large peaks in the schedulers memory usage.\nThis setting should be used to prevent these peaks."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"RESTResponseSize")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package"),(0,l.yg)("li",{parentName:"ul"},"Default value: 10,000")),(0,l.yg)("h2",{id:"performance-considerations"},"Performance considerations"),(0,l.yg)("h3",{id:"memory-usage-of-historical-elements"},"Memory usage of historical elements"),(0,l.yg)("p",null,"We need to estimate how many elements we can expect to be generated with different pod churn rates on a daily basis.\nQueue and node events are much rarer, so they are not accounted for.\nWe also ignore potential failures and scheduling errors."),(0,l.yg)("p",null,"An application undergoes state transitions, so the following events are generated:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Add new application"),(0,l.yg)("li",{parentName:"ul"},"State change: New"),(0,l.yg)("li",{parentName:"ul"},"State change: Accepted"),(0,l.yg)("li",{parentName:"ul"},"State change: Starting"),(0,l.yg)("li",{parentName:"ul"},"State change: Running"),(0,l.yg)("li",{parentName:"ul"},"State change: Completing"),(0,l.yg)("li",{parentName:"ul"},"State change: Completed"),(0,l.yg)("li",{parentName:"ul"},"Allocation changed")),(0,l.yg)("p",null,"Pod (request) events:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Incoming allocation request"),(0,l.yg)("li",{parentName:"ul"},"Successful allocation on a node")),(0,l.yg)("p",null,"Pod (request) events with gang scheduling:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Incoming resource request"),(0,l.yg)("li",{parentName:"ul"},"Successful allocation on a node"),(0,l.yg)("li",{parentName:"ul"},"Replace event for placeholder")),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Number of pods"),(0,l.yg)("th",{parentName:"tr",align:null},"Number of apps"),(0,l.yg)("th",{parentName:"tr",align:null},"Pods per app"),(0,l.yg)("th",{parentName:"tr",align:null},"Job type"),(0,l.yg)("th",{parentName:"tr",align:null},"Events per app"),(0,l.yg)("th",{parentName:"tr",align:null},"Events per pod"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 apps"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 pods"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 events"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"150k"),(0,l.yg)("td",{parentName:"tr",align:null},"1500"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"normal"),(0,l.yg)("td",{parentName:"tr",align:null},"200 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"2"),(0,l.yg)("td",{parentName:"tr",align:null},"310k (1500 * 207)"),(0,l.yg)("td",{parentName:"tr",align:null},"300k (2 * 150k)"),(0,l.yg)("td",{parentName:"tr",align:null},"610k")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"150k"),(0,l.yg)("td",{parentName:"tr",align:null},"1500"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"gang"),(0,l.yg)("td",{parentName:"tr",align:null},"300 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"3"),(0,l.yg)("td",{parentName:"tr",align:null},"460k (1500 * 307)"),(0,l.yg)("td",{parentName:"tr",align:null},"450k (3 * 150k)"),(0,l.yg)("td",{parentName:"tr",align:null},"910k")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"300k"),(0,l.yg)("td",{parentName:"tr",align:null},"3000"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"normal"),(0,l.yg)("td",{parentName:"tr",align:null},"200 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"2"),(0,l.yg)("td",{parentName:"tr",align:null},"621k (3000 * 207)"),(0,l.yg)("td",{parentName:"tr",align:null},"600k (2 * 300k)"),(0,l.yg)("td",{parentName:"tr",align:null},"1,2M")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"300k"),(0,l.yg)("td",{parentName:"tr",align:null},"3000"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"gang"),(0,l.yg)("td",{parentName:"tr",align:null},"300 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"3"),(0,l.yg)("td",{parentName:"tr",align:null},"921k (3000 * 307)"),(0,l.yg)("td",{parentName:"tr",align:null},"900k (3 * 300k)"),(0,l.yg)("td",{parentName:"tr",align:null},"1,8M")))),(0,l.yg)("p",null,"On a busy cluster with 150,000 - 300,000 pods per day, we can expect the number of events generated to be around 600k - 1,8M (depending on the scheduling style)."),(0,l.yg)("p",null,"If we want to retain the events for 5 days, we need to store 9 million events in the worst case and 3 million in the best case."),(0,l.yg)("p",null,"With 9 million objects in the memory, it is also critical to estimate how much extra memory usage is expected from YuniKorn with different kinds of data structures:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"slice of pointers to si.EventRecord objects ",(0,l.yg)("inlineCode",{parentName:"li"},"[]*si.EventRecord")),(0,l.yg)("li",{parentName:"ul"},"slice of si.EventRecord objects ",(0,l.yg)("inlineCode",{parentName:"li"},"[]si.EventRecord")),(0,l.yg)("li",{parentName:"ul"},"slice of a memory-optimised data type ",(0,l.yg)("inlineCode",{parentName:"li"},"[]internalRecord"))),(0,l.yg)("p",null,"As the name suggests, internalRecord type would only be available inside the ring buffer.\nIt's used together with string interning to save memory caused by repeated strings like IDs (application ID, ask ID, allocation ID, etc.).\nThere are various interning libraries in Go, but removing elements is not possible from them.\nWe need to create our own, so we can track the number of references per string."),(0,l.yg)("p",null,"The following table summarizes memory usage and GC time, depending on how we store the events.\nThe test was executed multiple times to get averages and ranges.\nThe slice was created once, then an index variable was increased for each record, so the built-in ",(0,l.yg)("inlineCode",{parentName:"p"},"append()")," function was not used."),(0,l.yg)("p",null,"The results clearly indicate two things:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"having millions of pointers has negative performance on both the memory usage and GC load"),(0,l.yg)("li",{parentName:"ul"},"batch workloads inherently have a lot of repeated strings, so interning makes a noticeable difference")),(0,l.yg)("p",null,"The GC detects pointers, since it has to follow them to walk the object graph to identify unreferenced objects.\nIf elements in the slice are pointers, then those allocations are scattered all around the heap (bad locality) with header information added by the allocator.\nThis reduces memory access times and increases the amount of the data that is allocated."),(0,l.yg)("p",null,"In the test, the assumption was 100 pods per application.\nIn real life, this value might be different, most likely it's lower.\nThe lower the value, the smaller the advantage of the interning - on the extreme, every application consists of only one pod.\nBut even with only 30 pods per application, it has value - more modest, 20-30% reductions are not negligible when storing millions of elements."),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Object type"),(0,l.yg)("th",{parentName:"tr",align:null},"Number of elements"),(0,l.yg)("th",{parentName:"tr",align:null},"Increased memory usage","*"),(0,l.yg)("th",{parentName:"tr",align:null},"GC time","*","*"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"805 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"85-105 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"437 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"41-55 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"211 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"5-16 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"1595 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"160-200 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"856 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"75-110 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"404 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"10-30 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"2380 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"270-320 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"1280 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"116-150 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"593 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"16-33 ms")))),(0,l.yg)("p",null,(0,l.yg)("em",{parentName:"p"},"*",' "Sys" metrics returned by the Go runtime')),(0,l.yg)("p",null,(0,l.yg)("em",{parentName:"p"},"*","*"," measured by the execution time of ",(0,l.yg)("inlineCode",{parentName:"em"},"runtime.GC()"))),(0,l.yg)("h3",{id:"handling-slow-and-rogue-clients-during-streaming"},"Handling slow and rogue clients during streaming"),(0,l.yg)("p",null,"It's possible to overwhelm YuniKorn with streaming or execute a DoS attack."),(0,l.yg)("p",null,"The first thing we need to address is a rogue client which simply stops reading on the receiver side from the TCP socket.\nEventually writes will block in YuniKorn.\nIf we use channels and per-client goroutines, this should not be an issue - we can always check if the buffer is full using the built-in len() function.\nIf this happens, we can just drop the connection.\nIn some situations, the buffer is expected to be full, for example, when sending history.\nIt's always faster to send out a lot of existing objects, so we can expect the buffer to get full at times.\nThis can be solved by repeatedly checking the rate of writes - if it falls below a certain threshold, then again, we just drop the connection with an error message."),(0,l.yg)("p",null,"We can also limit the number of concurrent streaming connections and historical objects to send, e.g. we simply won't serve requests which would result in sending millions of elements."),(0,l.yg)("p",null,"Note that it's still possible to deny the service from legitimate users because YuniKorn lacks authentication on the REST interface.\nThis will be solved in the future."),(0,l.yg)("h3",{id:"approaches-to-streaming"},"Approaches to streaming"),(0,l.yg)("p",null,"When a client requests a stream of events, it can define how many past events it wants to receive.\nThis is necessary because when YuniKorn starts up, it's not possible to connect immediately.\nIt can be important for certain users to save the state of YuniKorn on an external storage completely from the start."),(0,l.yg)("p",null,"Sending the historical events must be separated from the new events that are constantly occurring in the system, that is, old and current events must not interleave.\nFor example: we want a stream of old and new events, this means:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"We're currently at ",(0,l.yg)("em",{parentName:"li"},"event~n~")),(0,l.yg)("li",{parentName:"ul"},"Send out events from ",(0,l.yg)("em",{parentName:"li"},"event~0~")," all the way up to ",(0,l.yg)("em",{parentName:"li"},"event~n~")),(0,l.yg)("li",{parentName:"ul"},"In the meantime, ",(0,l.yg)("em",{parentName:"li"},"k")," number of events have been generated"),(0,l.yg)("li",{parentName:"ul"},"Therefore, send events up to event",(0,l.yg)("em",{parentName:"li"},"~n+k~")," until we're caught up completely")),(0,l.yg)("h4",{id:"send-history-first-then-stream-new-events"},(0,l.yg)("strong",{parentName:"h4"},"Send history first, then stream new events")),(0,l.yg)("p",null,"The first approach is to retrieve the objects from the ring buffer and start to send them on a channel to the receiver.\nThere is a separate buffered channel for new events with capacity ",(0,l.yg)("em",{parentName:"p"},"localBufferSize"),".\nAs soon as we finish sending the history, we switch to this channel and relay events from it towards the client."),(0,l.yg)("p",null,"We can express this with the following pseudocode:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"consumerEventLoop(elementCount) {\n local = initLocalEventChannel(localBufferSize)\n // send history\n history := ringbuffer.getHistory(elementCount)\n foreach h : history {\n receiver <- h\n }\n // bridge new events\n foreach e : <-local {\n receiver <- e\n }\n}\n")),(0,l.yg)("p",null,"The publisher logic is:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},'publishEvent(event) {\n foreach c : localChannels {\n if len(c) == localBufferSize { // local buffer full?\n closeChan(receiver)\n closeChan(local)\n receiverId = getReceiver(c)\n abort("slow receiver: " + receiverId)\n }\n c <- event\n }\n}\n')),(0,l.yg)("p",null,"Each receiver has its own goroutine.\nThat is, 10 clients means 10 different ",(0,l.yg)("inlineCode",{parentName:"p"},"consumerEventLoop()")," calls running on separate goroutines."),(0,l.yg)("p",null,"To detect slow clients, we simply check the value of ",(0,l.yg)("inlineCode",{parentName:"p"},"len(c)")," whenever we submit the new event.\nIf this equals the capacity of the buffer, we drop the receiver and close the connection."),(0,l.yg)("p",null,"It is possible to send events directly to the receiver channel and skip ",(0,l.yg)("inlineCode",{parentName:"p"},"c")," on the publisher side which is local inside consumerEventLoop.\nThis requires a simple state machine and a temporary slice of new events, since we are not allowed to send directly as long as the history is being transmitted.\nOverall, this is more complicated than the one described above."),(0,l.yg)("p",null,"The simplicity of this method is notable, which is the main advantage: reasoning about its correctness is trivial.\nWe do not need complicated test code and back-and-forth review cycles to ensure that it indeed results in the correct order of events."),(0,l.yg)("p",null,"The biggest question is what happens if channel local becomes full.\nLet's say that localBufferSize is 1000.\nOn a busy cluster with 100 events / second (busiest period), it takes 10 seconds to fill it up completely.\nHowever, nothing stops us from setting the capacity of the buffer to a higher value.\nIf we bump it up to 10000, the client is expected to read the history in 100 seconds.\nOn a decent network, this amount of time should be enough to read the event history, even if it means 100 000 entries from the ring buffer.\nIf a single si.EventRecord results in 300 bytes of JSON text, then it is around 30MiB of data.\nEven if we take serialisation into account, this will not (can not) take minutes."),(0,l.yg)("p",null,"The biggest disadvantage of this method is when a user requests a lot of elements from the history.\nFor example, someone wants to retrieve the last 1M elements.\nIn this case, we need to allocate a slice for 1M entries.\nBased on the measurements, this will generate a sudden spike in the live heap size, around 145-150 MiB. If people repeatedly do this, the memory allocation of YuniKorn can increase very quickly, possibly resulting in a termination of the YuniKorn pod by the kubelet."),(0,l.yg)("h4",{id:"stream-new-events-directly-from-ring-buffer"},(0,l.yg)("strong",{parentName:"h4"},"Stream new events directly from ring buffer")),(0,l.yg)("p",null,"Instead of notifying receivers directly, we just insert the data into the ring buffer.\nFor every client, we create a cursor which points to a given position inside the buffer.\nIf the pointer is behind the tail, it just keeps reading and going forward until it reaches the current tail."),(0,l.yg)("p",null,"Although this method sounds simple on the surface, the implementation is complicated:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"When sending the history, we can't rely on ",(0,l.yg)("inlineCode",{parentName:"li"},"len(buf)")," checking.\nIt is because when we are sending the history, we are always very close to the capacity.\nUnlike the previous solution, we are processing elements from the buffer directly, and we do not bridge two channels.\nIf we do that, we just add further complications.\nTherefore, we have to calculate the sending rate, at least while sending past objects.\nIf the pointer is not making progress (or just very slow), then the tail of the ring buffer will catch up to it, but it can take a very long time."),(0,l.yg)("li",{parentName:"ul"},"In case of multiple cursors, we have to maintain which one is the closest to the tail.\nIf we don't do that, we have to check every cursor when adding elements.\nWe cannot wait for a slow reader to jump to the next element, so we have to invalidate the cursor, then have to calculate which is the nearest to tail again."),(0,l.yg)("li",{parentName:"ul"},"Whenever we reach the last element, we have to block and utilize the well-known wait-notify pattern (",(0,l.yg)("inlineCode",{parentName:"li"},"Cond.Broadcast()")," and ",(0,l.yg)("inlineCode",{parentName:"li"},"Cond.Wait()")," in Go)."),(0,l.yg)("li",{parentName:"ul"},"The overall sending logic is much more complicated: keep reading batches from the ring buffer until we reach the last element, then switch to wait-notify and block.")),(0,l.yg)("p",null,"The advantage of this method is that we don't need large channel buffers to make sure that they don't get filled while sending historical records.\nIf the reader is fast enough, we just keep marshalling ",(0,l.yg)("inlineCode",{parentName:"p"},"si.EventRecord")," objects and bump the pointer to the next element."),(0,l.yg)("div",{className:"footnotes"},(0,l.yg)("hr",{parentName:"div"}),(0,l.yg)("ol",{parentName:"div"},(0,l.yg)("li",{parentName:"ol",id:"fn-1"},(0,l.yg)("a",{parentName:"li",href:"https://pkg.go.dev/strconv#ParseBool"},"https://pkg.go.dev/strconv#ParseBool"),(0,l.yg)("a",{parentName:"li",href:"#fnref-1",className:"footnote-backref"},"\u21a9")),(0,l.yg)("li",{parentName:"ol",id:"fn-2"},(0,l.yg)("a",{parentName:"li",href:"https://pkg.go.dev/strconv#ParseUint"},"https://pkg.go.dev/strconv#ParseUint"),(0,l.yg)("a",{parentName:"li",href:"#fnref-2",className:"footnote-backref"},"\u21a9")))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/073760cf.fb1e0443.js b/assets/js/073760cf.fb1e0443.js new file mode 100644 index 00000000000..41e8b8c5afe --- /dev/null +++ b/assets/js/073760cf.fb1e0443.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[60043],{58860:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>y});var a=n(37953);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=a.createContext({}),g=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=g(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=g(n),m=l,y=d["".concat(s,".").concat(m)]||d[m]||u[m]||r;return n?a.createElement(y,i(i({ref:t},p),{},{components:n})):a.createElement(y,i({ref:t},p))}));function y(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=n.length,i=new Array(r);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:l,i[1]=o;for(var g=2;g{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>g});var a=n(72994),l=(n(37953),n(58860));const r={id:"historical_usage_tracking",title:"Historical Usage Tracking"},i=void 0,o={unversionedId:"design/historical_usage_tracking",id:"design/historical_usage_tracking",title:"Historical Usage Tracking",description:"\x3c!--",source:"@site/docs/design/historical_usage_tracking.md",sourceDirName:"design",slug:"/design/historical_usage_tracking",permalink:"/docs/next/design/historical_usage_tracking",draft:!1,tags:[],version:"current",frontMatter:{id:"historical_usage_tracking",title:"Historical Usage Tracking"},sidebar:"docs",previous:{title:"User Based Quota Enforcement",permalink:"/docs/next/design/user_group_resource_usage_enforcement"},next:{title:"Simplifying Interface Messages",permalink:"/docs/next/design/interface_message_simplification"}},s={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:2},{value:"Non Goals",id:"non-goals",level:2},{value:"Existing Event System",id:"existing-event-system",level:2},{value:"Scheduler integration",id:"scheduler-integration",level:3},{value:"Event storage",id:"event-storage",level:3},{value:"Publishing events",id:"publishing-events",level:3},{value:"Event System Updates",id:"event-system-updates",level:2},{value:"Event description",id:"event-description",level:3},{value:"Event types",id:"event-types",level:3},{value:"Change types",id:"change-types",level:3},{value:"Change details",id:"change-details",level:3},{value:"Content definition",id:"content-definition",level:3},{value:"Event storage",id:"event-storage-1",level:2},{value:"Publishing events",id:"publishing-events-1",level:3},{value:"SHIM events",id:"shim-events",level:4},{value:"REST",id:"rest",level:4},{value:"Streaming",id:"streaming",level:4},{value:"Event overview",id:"event-overview",level:2},{value:"Generic events",id:"generic-events",level:3},{value:"Shim events",id:"shim-events-1",level:3},{value:"Configuration",id:"configuration",level:2},{value:"Performance considerations",id:"performance-considerations",level:2},{value:"Memory usage of historical elements",id:"memory-usage-of-historical-elements",level:3},{value:"Handling slow and rogue clients during streaming",id:"handling-slow-and-rogue-clients-during-streaming",level:3},{value:"Approaches to streaming",id:"approaches-to-streaming",level:3},{value:"Send history first, then stream new events",id:"send-history-first-then-stream-new-events",level:4},{value:"Stream new events directly from ring buffer",id:"stream-new-events-directly-from-ring-buffer",level:4}],p={toc:g},d="wrapper";function u(e){let{components:t,...n}=e;return(0,l.yg)(d,(0,a.A)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,l.yg)("h2",{id:"introduction"},"Introduction"),(0,l.yg)("p",null,"Tracking an application lifecycle is not easy in the current YuniKorn setup.\nLogs and statedump data is required to build an overview.\nHistorical tracking of applications is only possible with limited detail per application.\nApplications come and go, we only track what is running and a time limited set of completed applications."),(0,l.yg)("p",null,"Storing detailed tracking information in memory is problematic.\nUnbound growth can cause performance issues or even an out of memory failure of the service.\nThe lessons learned from the YARN days have shown that it is not simple."),(0,l.yg)("p",null,"A conscious choice was also made to keep YuniKorn stateless.\nThe service does not maintain its own datastore for any of its operations.\nAdding a datastore for application and usage tracking will complicate things."),(0,l.yg)("p",null,"Tracking data can be easily generated and made available for external consumption.\nThe design will discuss the option to generate an event stream for applications, queues and nodes to allow external tools to build an overview of the usage pattern."),(0,l.yg)("p",null,"Work to be tracked under ",(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-1628"},"YUNIKORN-1628")),(0,l.yg)("h2",{id:"goals"},"Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for an application, including: ",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Asks and allocation changes"))),(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for a node, including:",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Allocation changes"))),(0,l.yg)("li",{parentName:"ul"},"Implementation of an event stream for a queue, including:",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"State changes"),(0,l.yg)("li",{parentName:"ul"},"Usage changes"))),(0,l.yg)("li",{parentName:"ul"},"Define a REST interface for event retrieval")),(0,l.yg)("h2",{id:"non-goals"},"Non Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Add a data store for the historical data"),(0,l.yg)("li",{parentName:"ul"},"Display the event information"),(0,l.yg)("li",{parentName:"ul"},"Rebuild data on recovery",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Historical data will not be rebuild"))),(0,l.yg)("li",{parentName:"ul"},"Authentication and Authorisation on the REST interface")),(0,l.yg)("h2",{id:"existing-event-system"},"Existing Event System"),(0,l.yg)("p",null,"The event system was designed to be far more flexible than the current usage.\nEvents for requests, applications, nodes and queues have been defined.\nMost of those are currently not used.\nThe current event system is built on top of a generic event definition.\nThe scheduler interface defines the event as:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"si.EventRecord {\n Type: recordType,\n ObjectID: String,\n GroupID: String,\n Reason: String,\n Message: String,\n TimestampNano: int64,\n}\n")),(0,l.yg)("p",null,"Events definitions are used in the core and shim.\nThe simplicity of the events will most likely not match the current requirements."),(0,l.yg)("p",null,"As part of the standard scheduling cycle we track details at different levels.\nPrometheus' metrics are tracked for specific changes and updates.\nWe also generate events, REQUEST events, that get passed back into the K8shim to attach to the Kubernetes pods."),(0,l.yg)("p",null,"The current events that get passed back are for:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("em",{parentName:"li"},"Insufficient Queue Resources"),": part of the allocation cycle. Called from: ",(0,l.yg)("inlineCode",{parentName:"li"},"Application.tryAllocate()")),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("em",{parentName:"li"},"Placeholder Size Mismatch"),": part of the placeholder replacement cycle. Called from: ",(0,l.yg)("inlineCode",{parentName:"li"},"Application.tryPlaceholderAllocate()"))),(0,l.yg)("p",null,"Both events are of the type REQUEST.\nThe K8shim also implements processing of NODE events but there is no code that generates those types of events.\nThe APPLICATION and QUEUE type events are not created or processed."),(0,l.yg)("p",null,"The event system was added as part of ",(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-42"},"YUNIKORN-42"),".\nThe jira contains a simple design document for the event system.\nIt only was implemented for events that we could not at that point get in any other way: ",(0,l.yg)("a",{parentName:"p",href:"https://docs.google.com/document/d/1aKfY6wnBPCyBl03UfmMHbTSpabAbfxtsHT2KzOgEOQs/edit"},"design v2"),".\nThe original thought was a more generic event system.\nIt would relate everything back to either a pod or the YuniKorn CRD and was focussed on diagnostics and troubleshooting in general: ",(0,l.yg)("a",{parentName:"p",href:"https://docs.google.com/document/d/19iMkLJGVwTSq9OfV9p75wOobJXAxR_CRo4YzSRG_Pzw/edit#heading=h.worp3vfnqgtn"},"design v1"),".\nLinking it all back to a specific pod is The YuniKorn CRD is not used at this point in time."),(0,l.yg)("h3",{id:"scheduler-integration"},"Scheduler integration"),(0,l.yg)("p",null,"When the event system was designed the whole purpose was to allow out of band processing of the events from the scheduling cycle.\nThe events are generated during the scheduling cycle and processed asynchronously in the event system."),(0,l.yg)("p",null,"A channel is used for collecting the events during the scheduling cycle.\nThe scheduler generates an event and adds it for processing to the channel.\nAfter the placement of the event on the channel the scheduler proceeds with the normal cycle.\nProcessing of the events does not, and must not, block the scheduling cycle."),(0,l.yg)("p",null,"This part of the event system must be maintained as it will guarantee the performance of the scheduler."),(0,l.yg)("h3",{id:"event-storage"},"Event storage"),(0,l.yg)("p",null,"All events that have been sent to the channel are read from the channel and placed in a temporary store for publishing.\nThe store is a simple map with the key of the ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),"."),(0,l.yg)("p",null,"Some of the assumptions in the event store however make it not directly usable for the purpose as described here.\nThe main limitation is that there can only be one event in the channel per ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),".\nThe newest one is kept, the older one is dropped when a new event comes in.\nThis however does not mean the code already available with minor changes could be re-used for this purpose."),(0,l.yg)("h3",{id:"publishing-events"},"Publishing events"),(0,l.yg)("p",null,"The current event system uses a push system for event publishing.\nThe event system allows the creation of multiple event publishers.\nThere is no implementation or design for a pull system, like for instance a REST based interface."),(0,l.yg)("p",null,"Currently, there is only an event publisher for a shim defined.\nThis push system will send all the events that have been collected during the push interval to the shim.\nAll events that are pushed will be removed from the store.\nThis keeps the size of the store to a minimum."),(0,l.yg)("p",null,"There is no filtering or post-processing of events implemented.\nEach event stored in the store is forwarded to the shim when the publisher runs.\nSee limitations of the store mentioned above.\nIn the earlier design a level filter was described.\nThat level was never part of the follow-up design, not in the events and not in the processing."),(0,l.yg)("h2",{id:"event-system-updates"},"Event System Updates"),(0,l.yg)("p",null,"The currently defined events are not a fit for the system we want and need.\nSince the events are only used between the core and the K8shim via the publisher we do not need to maintain backwards compatibility.\nChanges can be made to the messages as we do not currently expose the message to the outside."),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"message")," and ",(0,l.yg)("em",{parentName:"p"},"reason")," fields are currently not properly used.\nThe content of the two overlaps.\nThe message in both cases contains the reason, in slightly different wording.\nWe do not need both."),(0,l.yg)("h3",{id:"event-description"},"Event description"),(0,l.yg)("p",null,"We are also missing two fields to allow an extended usage for historical tracking: the ",(0,l.yg)("em",{parentName:"p"},"resource")," and the ",(0,l.yg)("em",{parentName:"p"},"change type"),".\nBased on that the new message that would allow using the event system for tracking historical change would be:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"si.EventRecord {\n Type: eventRecordType,\n ChangeType: eventChangeType,\n ChangeDetail: eventChangeDetail,\n TimestampNano: int64,\n ObjectID: String,\n ReferenceID: String,\n Resource: si.Resource,\n Message: String,\n}\n")),(0,l.yg)("p",null,"The existing ",(0,l.yg)("em",{parentName:"p"},"GroupID")," has been renamed to ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),". The\n",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is the identification of the second object for the event.\nAs an example that would be the Allocation UUID for a new allocation\nadded to an application, request or node. For the queue that would be\nthe application ID."),(0,l.yg)("p",null,"Note that the order of the attributes in the final definition might be\ndifferent as we do not reuse names and IDs in the messages."),(0,l.yg)("h3",{id:"event-types"},"Event types"),(0,l.yg)("p",null,"By keeping the event type for REQUESTS we can still fulfil the original\ndesign of YUNIKORN-42. The current enumeration for the ",(0,l.yg)("em",{parentName:"p"},"eventRecordType"),"\nwould not change. Definition of the eventRecordType enumeration:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"UNKNOWN = 0\nREQUEST = 1\nAPP = 2\nNODE = 3\nQUEUE = 4\n")),(0,l.yg)("h3",{id:"change-types"},"Change types"),(0,l.yg)("p",null,"The additional change type that is added allows us to track the type of\nchange. Depending on the content of the other fields it provides the\npossibility to track all changes we need to track. Definition of the\neventChangeType enumeration:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"NONE = 0\nSET = 1\nADD = 2\nREMOVE = 3\n")),(0,l.yg)("h3",{id:"change-details"},"Change details"),(0,l.yg)("p",null,"Change detail provides more on the reason for the event. The change\ndetail is an enumerated value linked to the event types."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"DETAILS_NONE = 0\n\nREQUEST_CANCEL = 100 // Request cancelled by the RM\nREQUEST_ALLOC = 101 // Request allocated\nREQUEST_TIMEOUT = 102 // Request cancelled due to timeout\n\nAPP_ALLOC = 200 // Allocation changed\nAPP_REQUEST = 201 // Request changed\nAPP_REJECT = 202 // Application rejected on create\nAPP_NEW = 203 // Application added with state new\nAPP_ACCEPTED = 204 // State change to accepted\nAPP_RUNNING = 206 // State change to running\nAPP_COMPLETING = 207 // State change to completing\nAPP_COMPLETED = 208 // State change to completed\nAPP_FAILING = 209 // State change to failing\nAPP_FAILED = 210 // State change to failed\nAPP_RESUMING = 211; // State change to resuming\nAPP_EXPIRED = 212; // State change to expired\n\nNODE_DECOMISSION = 300 // Node removal\nNODE_READY = 301 // Node ready state change\nNODE_SCHEDULABLE = 302 // Node schedulable state change (cordon)\nNODE_ALLOC = 303 // Allocation changed\nNODE_CAPACITY = 304 // Capacity changed\nNODE_OCCUPIED = 305 // Occupied resource changed\nNODE_RESERVATION = 306; // Reservation/unreservation occurred\n\nQUEUE_CONFIG = 400 // Managed queue update or removal\nQUEUE_DYNAMIC = 401 // Dynamic queue update or removal\nQUEUE_TYPE = 402 // Queue type change\nQUEUE_MAX = 403 // Max resource changed\nQUEUE_GUARANTEED = 404 // Guaranteed resource changed\nQUEUE_APP = 405 // Application changed\nQUEUE_ALLOC = 406 // Allocation changed\nALLOC_CANCEL = 500 // Allocation cancelled by the RM\nALLOC_PREEMPT = 501 // Allocation preempted by the core\nALLOC_TIMEOUT = 502 // Allocation cancelled due to timeout\nALLOC_REPLACED = 503 // Allocation replacement (placeholder)\nALLOC_NODEREMOVED = 504 // Allocation cancelled, node removal\n")),(0,l.yg)("h3",{id:"content-definition"},"Content definition"),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"eventRecordType")," defines the object that the ",(0,l.yg)("em",{parentName:"p"},"ObjectID")," points to.\nThe content of the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," depends on two things:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Change type"),(0,l.yg)("li",{parentName:"ul"},"Object type inferred by the ",(0,l.yg)("em",{parentName:"li"},"eventRecordType"))),(0,l.yg)("p",null,"For an object of type application it would not make sense to have the reference point to another application etc.\nAt this point the following mapping for ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is assumed:"),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event Type"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference ID"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"Allocation UUID or Request UUID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"Allocation UUID")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID or Allocation UUID")))),(0,l.yg)("p",null,"If the ",(0,l.yg)("em",{parentName:"p"},"eventChangeType")," Is NONE or SET the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is always empty.\nThe exception is for the REQUEST as in that case the change type NONE has an application ID set.\nThis special case is used to implement the existing functionality of the event system: sending events to the shim."),(0,l.yg)("p",null,"The APP record type supports Request IDs and Allocation UUIDs to be set in the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),".\nThe type of ID that is referenced is defined by the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail"),"."),(0,l.yg)("p",null,"The QUEUE record type supports application IDs and Allocation UUIDs to be set in the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID"),".\nIndividual allocations are not tracked on the queue.\nHowever, we leave that option open for the event system at this point."),(0,l.yg)("p",null,"For the QUEUE if ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," and ",(0,l.yg)("em",{parentName:"p"},"Resource")," are set, the ID points to an allocation.\nThis can only happen if the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail")," is set to QUEUE_ALLOC."),(0,l.yg)("p",null,"If only the ",(0,l.yg)("em",{parentName:"p"},"ReferenceID")," is set it points to an application.\nThis can only happen if the ",(0,l.yg)("em",{parentName:"p"},"ChangeDetail")," is set to QUEUE_APP.\nBoth cases can use the same ",(0,l.yg)("em",{parentName:"p"},"eventChangeType"),", add or remove an allocation or an application from a queue."),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"Resource")," that is part of any event would be the size of the resource for that change.\nThe interpretation depends on the ",(0,l.yg)("em",{parentName:"p"},"eventChangeType"),".\nFor a SET it is the absolute value. For the ADD and REMOVE it is the positive delta on the existing tracked value.\nThe ",(0,l.yg)("em",{parentName:"p"},"Resource")," is always a positive value."),(0,l.yg)("h2",{id:"event-storage-1"},"Event storage"),(0,l.yg)("p",null,"The storage of events needs to be updated to allow multiple events to be stored for an ",(0,l.yg)("em",{parentName:"p"},"ObjectID"),".\nThis is required as one object could trigger multiple events in a short time and all are important to track.\nThis will require a change from a map based storage to a different store or a change in the key used for the map."),(0,l.yg)("p",null,"The simplest solution might be a slice of pointers to events.\nThe slice has a configurable, limited set of entries.\nThe slice is accessed and maintained as a ring buffer.\nThis will prevent an unlimited growth of the schedulers memory requirements.\nDuring the implementation a decision will be made which configuration, time; count or both, for limiting the size will be supported."),(0,l.yg)("p",null,"Nil, or empty, events will not be added to the storage.\nHowever, no publisher must assume that while processing events retrieved from the buffer and needs to handle nil references.\nA location in the buffer could contain a nil pointer and must be skipped while iterating over the buffer.\nIf a publisher gets a nil event pointer it must not crash and proceed as normal."),(0,l.yg)("p",null,"The current design will use two stores: one for external retrieval and one for the shim events.\nA filter at the receiving end will be created.\nThe shim events will then be processed as per the existing implementation.\nThe new events will be stored and managed as per this design document in ",(0,l.yg)("a",{parentName:"p",href:"#shim-events"},"SHIM events"),"."),(0,l.yg)("h3",{id:"publishing-events-1"},"Publishing events"),(0,l.yg)("p",null,"Events are currently not post processed and all events are sent to the shim.\nWith the newly added events the publishing needs to be split into two separate loops."),(0,l.yg)("h4",{id:"shim-events"},"SHIM events"),(0,l.yg)("p",null,"Current functionality will be supported as described above.\nUpdates are required as the content of the events has changed.\nThe same event type will be generated.\nThe same processing mechanism will be used."),(0,l.yg)("p",null,"As part of processing events REQUEST type events are special.\nThe REQUEST type with the change type NONE has an application ID set and is only sent as an event to the shim.\nThese events must not be made available by any other publishers and are stored in a separate ring buffer.\nAfter the event is sent to the shim the reference to the event in the buffer is cleared, replaced with a nil."),(0,l.yg)("h4",{id:"rest"},"REST"),(0,l.yg)("p",null,"The REST service that is currently running can be reused for exposing the events.\nProposal is to add a new endpoint to the HTTP service.\nThe REST endpoint servicing the event data should be a new end point."),(0,l.yg)("p",null,"Based on the current REST api definition the data exposed in the following new endpoint will be added to expose the events:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/batch\n")),(0,l.yg)("p",null,"The design will not define a sophisticated interface for querying events, like filtering, grouping, etc.\nThis is a deliberate decision.\nSuch an API can encourage bad practices later on.\nThat should be done in a separate application which fetches the events from YuniKorn and persists them in a permanent storage and offers a more feature rich REST/query interface.\nThis would be similar to what already exists in Apache Hadoop like Job History Server or Application Timeline Service."),(0,l.yg)("p",null,"As mentioned earlier in this document, such an application is not in the scope."),(0,l.yg)("p",null,"The batch endpoint, by default, returns a limited number of events.\nThe number of events to return can be specifically set via the query parameter ",(0,l.yg)("em",{parentName:"p"},"count"),".\nIf the requested ",(0,l.yg)("em",{parentName:"p"},"count")," is larger than the available number of events all events are returned."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/batch?count=100\n")),(0,l.yg)("p",null,"To prevent a DOS attack the maximum value of ",(0,l.yg)("em",{parentName:"p"},"count")," might be limited as part of the implementation."),(0,l.yg)("p",null,"The second query parameter that will be supported is ",(0,l.yg)("em",{parentName:"p"},"start"),".\nThis specifies the start ID of the first event returned.\nEvery event is assigned a unique id starting from 0.\nThe ring buffer maintains the current available highest and lowest ID.\nIf ",(0,l.yg)("em",{parentName:"p"},"start")," refers to an ID which doesn't exist in the buffer, then an empty response is returned from the server, with ",(0,l.yg)("em",{parentName:"p"},"LowestID")," and ",(0,l.yg)("em",{parentName:"p"},"HighestID")," properly filled:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-json",metastring:"lines",lines:!0},'{\n "InstanceUUID": "b4751b7d-a1a3-4431-bb68-bff896adb9c2",\n "LowestID": 1100,\n "HighestID": 11000,\n "EventRecords": null\n}\n')),(0,l.yg)("p",null,"In the next request, start should be defined as 1100."),(0,l.yg)("p",null,"In the response, the ",(0,l.yg)("em",{parentName:"p"},"InstanceUUID")," field shows the unique instance ID.\nSince YuniKorn is stateless, the generated ID for an event is not saved anywhere.\nIf an event consumer saves the events to a backend database, it makes it possible to distinguish between events with the same ID.\nAlso, clients can easily detect that YuniKorn was restarted."),(0,l.yg)("h4",{id:"streaming"},"Streaming"),(0,l.yg)("p",null,'Streaming allows the user to see a continuous stream of events as they are occurring.\nThis can be very useful if we want to trace the state changes inside YuniKorn for a longer amount of time.\nThe REST interface can return the last "n" amount of events that occurred in a certain timeframe, but it will always be limited.\nWe can only increase the number of events at the expense of memory usage, which might not be acceptable in certain environments.'),(0,l.yg)("p",null,'Although streaming is a nice feature, we do not consider it as a "must have", at least not in the first version of the history tracking.\nThis is because it\'s more complicated in nature: it maintains an open HTTP connection towards the client which makes it stateful.\nThere are ordering and memory usage concerns&considerations.\nWe need to make sure that rogue clients cannot abuse it.\nTherefore, the first release of history tracking focuses on the batch interface.'),(0,l.yg)("p",null,"Streaming needs to coexist beside the current REST api.\nA separate endpoint must be exposed for the event stream:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-text"},"/ws/v1/events/stream\n")),(0,l.yg)("p",null,"Streaming can be similar to how it's implemented inside Kubernetes informers.\nThe API server keeps the connection alive and sends the necessary events about pods, nodes, configmaps, etc.\nThe incoming data stream is decoded by the listeners.\nEvent processing on the client side is not part of this design."),(0,l.yg)("p",null,"At this point we do not provide endpoints for consumers to stream a specific event type as defined in ",(0,l.yg)("a",{parentName:"p",href:"#event-types"},"Event types"),".\nThis could be made available via separate endpoints in the future following the same design as for ",(0,l.yg)("em",{parentName:"p"},"batch")," specification"),(0,l.yg)("p",null,"The ",(0,l.yg)("em",{parentName:"p"},"stream")," endpoint does not take any query parameters.\nThe consumer must allow for more than one (1) event to be sent in one response.\nNo information besides the events will be sent in the response."),(0,l.yg)("p",null,"As an example below the approximate output for the stream endpoint for two events"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "type": 2,\n "changeType": 1,\n "changeDetail": 203,\n "timestamp": 1649167576110750000,\n "objectID": "spark-app-1"\n },\n {\n "type": 4,\n "changeType": 2,\n "changeDetail": 405,\n "timestamp": 1649167576110754000,\n "objectID": "root.spark",\n "referenceID": "spark-app-1"\n }\n]\n')),(0,l.yg)("h2",{id:"event-overview"},"Event overview"),(0,l.yg)("h3",{id:"generic-events"},"Generic events"),(0,l.yg)("p",null,"The following events are generated for streaming and REST consumers, meaning that they will not be sent to the shim.\nThis is based on the description of the ",(0,l.yg)("a",{parentName:"p",href:"#event-system-updates"},"Event System Updates")," earlier in this document.\nIt serves as a reference for the core scheduler actions that will trigger the event."),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change details"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference type"),(0,l.yg)("th",{parentName:"tr",align:null},"Notes"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"New application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Incoming resource request (pod)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal of application")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REJECT"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Application rejected")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_CANCEL"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_TIMEOUT"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Timeout")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_REPLACED"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Replacement (placeholder)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_PREEMPT"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Preemption triggered")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"ALLOC_NODEREMOVED"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Removal triggered by node removal")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST_TIMEOUT"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Timeout (placeholder)")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST_CANCEL"),(0,l.yg)("td",{parentName:"tr",align:null},"RequestID"),(0,l.yg)("td",{parentName:"tr",align:null},"Removal triggered by application removal")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_NEW"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: New")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_ACCEPTED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Accepted")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_RUNNING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Running")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_COMPLETING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Completing")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_COMPLETED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Completed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_FAILING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Failing")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_FAILED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Failed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_RESUMING"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Resuming")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"APP"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"APP_EXPIRED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"State change: Expired")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null})),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"New node added to the cluster")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_DECOMISSION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_ALLOC"),(0,l.yg)("td",{parentName:"tr",align:null},"AllocationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Normal allocation removal requested by the shim")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_READY"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},'Update "ready" status')),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_SCHEDULABLE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},'Update "schedulable" status')),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_CAPACITY"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Update node capacity")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_OCCUPIED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Update occupied resources")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_RESERVATION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Add reservation to a node")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"NODE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"NODE_RESERVATION"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Remove reservation from a node")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null})),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Adding new configured queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_DYNAMIC"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Adding new dynamic queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"ADD"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removing configured queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_DYNAMIC"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Removing dynamic queue")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"REMOVE"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_APP"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Application removed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_MAX"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Max resource changed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_GUARANTEED"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Guaranteed resource changed")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE"),(0,l.yg)("td",{parentName:"tr",align:null},"SET"),(0,l.yg)("td",{parentName:"tr",align:null},"QUEUE_TYPE"),(0,l.yg)("td",{parentName:"tr",align:null}),(0,l.yg)("td",{parentName:"tr",align:null},"Queue type change(parent/leaf)")))),(0,l.yg)("h3",{id:"shim-events-1"},"Shim events"),(0,l.yg)("p",null,"Shim events are a type of REQUEST and the application ID is set.\nRight now we send only two types of events to the shim, both of which are originated from the application:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Insufficient resources in the queue for a request"),(0,l.yg)("li",{parentName:"ul"},"Real allocation is larger than placeholder")),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Event type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change type"),(0,l.yg)("th",{parentName:"tr",align:null},"Change details"),(0,l.yg)("th",{parentName:"tr",align:null},"Reference type"),(0,l.yg)("th",{parentName:"tr",align:null},"Notes"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"New application added")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"REQUEST"),(0,l.yg)("td",{parentName:"tr",align:null},"NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"DETAILS_NONE"),(0,l.yg)("td",{parentName:"tr",align:null},"ApplicationID"),(0,l.yg)("td",{parentName:"tr",align:null},"Successful allocation")))),(0,l.yg)("h2",{id:"configuration"},"Configuration"),(0,l.yg)("p",null,"As part of the design we anticipate the following configuration to be added for the event storage and retrieval.\nAll settings will have the shared prefix: ",(0,l.yg)("em",{parentName:"p"},"service.event"),".\nAll the mentioned settings will require a restart of the scheduler for updates to take effect."),(0,l.yg)("p",null,"The following settings will be added to the system:"),(0,l.yg)("p",null,"A flag to enable or disable sending request events to the K8shim.\nThis externalises the current setting that needs a recompile of the code.\nThe default mirrors the current default in the code."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"requestEventsEnabled")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: all boolean values will be converted into a boolean using ParseBool as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package",(0,l.yg)("sup",{parentName:"li",id:"fnref-1"},(0,l.yg)("a",{parentName:"sup",href:"#fn-1",className:"footnote-ref"},"1")),"."),(0,l.yg)("li",{parentName:"ul"},"Default value: false")),(0,l.yg)("p",null,"A flag to enable or disable event collection in the system.\nThe default is enabled for the tracking events."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"trackingEventsEnabled")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: all boolean values will be converted into a boolean using ParseBool as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package."),(0,l.yg)("li",{parentName:"ul"},"Default value: true")),(0,l.yg)("p",null,"Size of the store for events that will be sent to the shim, request events.\nNote that setting a size of 0 effectively turns off the request event system."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"requestStoreCapacity")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package",(0,l.yg)("sup",{parentName:"li",id:"fnref-2"},(0,l.yg)("a",{parentName:"sup",href:"#fn-2",className:"footnote-ref"},"2")),"."),(0,l.yg)("li",{parentName:"ul"},"Default value: 1,000")),(0,l.yg)("p",null,"The number of events to store in the ring buffer.\nThis number defines the size of the ring buffer and thus the memory impact the event storage will have on the scheduler.\nNote that setting a size of 0 effectively turns off the event collection system."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"ringBufferCapacity")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package"),(0,l.yg)("li",{parentName:"ul"},"Default value: 100,000")),(0,l.yg)("p",null,"The maximum number of events to return in one REST response.\nThe maximum that could be returned is limited to the ring buffer capacity.\nHowever, preparing a large response the size of the whole ring buffer could cause large peaks in the schedulers memory usage.\nThis setting should be used to prevent these peaks."),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Name: ",(0,l.yg)("strong",{parentName:"li"},"RESTResponseSize")),(0,l.yg)("li",{parentName:"ul"},"Allowed values: integer value that can be converted into a 32-bit integer using ParseUint as defined in the ",(0,l.yg)("inlineCode",{parentName:"li"},"strconv")," package"),(0,l.yg)("li",{parentName:"ul"},"Default value: 10,000")),(0,l.yg)("h2",{id:"performance-considerations"},"Performance considerations"),(0,l.yg)("h3",{id:"memory-usage-of-historical-elements"},"Memory usage of historical elements"),(0,l.yg)("p",null,"We need to estimate how many elements we can expect to be generated with different pod churn rates on a daily basis.\nQueue and node events are much rarer, so they are not accounted for.\nWe also ignore potential failures and scheduling errors."),(0,l.yg)("p",null,"An application undergoes state transitions, so the following events are generated:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Add new application"),(0,l.yg)("li",{parentName:"ul"},"State change: New"),(0,l.yg)("li",{parentName:"ul"},"State change: Accepted"),(0,l.yg)("li",{parentName:"ul"},"State change: Running"),(0,l.yg)("li",{parentName:"ul"},"State change: Completing"),(0,l.yg)("li",{parentName:"ul"},"State change: Completed"),(0,l.yg)("li",{parentName:"ul"},"Allocation changed")),(0,l.yg)("p",null,"Pod (request) events:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Incoming allocation request"),(0,l.yg)("li",{parentName:"ul"},"Successful allocation on a node")),(0,l.yg)("p",null,"Pod (request) events with gang scheduling:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Incoming resource request"),(0,l.yg)("li",{parentName:"ul"},"Successful allocation on a node"),(0,l.yg)("li",{parentName:"ul"},"Replace event for placeholder")),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Number of pods"),(0,l.yg)("th",{parentName:"tr",align:null},"Number of apps"),(0,l.yg)("th",{parentName:"tr",align:null},"Pods per app"),(0,l.yg)("th",{parentName:"tr",align:null},"Job type"),(0,l.yg)("th",{parentName:"tr",align:null},"Events per app"),(0,l.yg)("th",{parentName:"tr",align:null},"Events per pod"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 apps"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 pods"),(0,l.yg)("th",{parentName:"tr",align:null},"\u2211 events"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"150k"),(0,l.yg)("td",{parentName:"tr",align:null},"1500"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"normal"),(0,l.yg)("td",{parentName:"tr",align:null},"200 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"2"),(0,l.yg)("td",{parentName:"tr",align:null},"310k (1500 * 207)"),(0,l.yg)("td",{parentName:"tr",align:null},"300k (2 * 150k)"),(0,l.yg)("td",{parentName:"tr",align:null},"610k")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"150k"),(0,l.yg)("td",{parentName:"tr",align:null},"1500"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"gang"),(0,l.yg)("td",{parentName:"tr",align:null},"300 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"3"),(0,l.yg)("td",{parentName:"tr",align:null},"460k (1500 * 307)"),(0,l.yg)("td",{parentName:"tr",align:null},"450k (3 * 150k)"),(0,l.yg)("td",{parentName:"tr",align:null},"910k")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"300k"),(0,l.yg)("td",{parentName:"tr",align:null},"3000"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"normal"),(0,l.yg)("td",{parentName:"tr",align:null},"200 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"2"),(0,l.yg)("td",{parentName:"tr",align:null},"621k (3000 * 207)"),(0,l.yg)("td",{parentName:"tr",align:null},"600k (2 * 300k)"),(0,l.yg)("td",{parentName:"tr",align:null},"1,2M")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"300k"),(0,l.yg)("td",{parentName:"tr",align:null},"3000"),(0,l.yg)("td",{parentName:"tr",align:null},"100"),(0,l.yg)("td",{parentName:"tr",align:null},"gang"),(0,l.yg)("td",{parentName:"tr",align:null},"300 + 7"),(0,l.yg)("td",{parentName:"tr",align:null},"3"),(0,l.yg)("td",{parentName:"tr",align:null},"921k (3000 * 307)"),(0,l.yg)("td",{parentName:"tr",align:null},"900k (3 * 300k)"),(0,l.yg)("td",{parentName:"tr",align:null},"1,8M")))),(0,l.yg)("p",null,"On a busy cluster with 150,000 - 300,000 pods per day, we can expect the number of events generated to be around 600k - 1,8M (depending on the scheduling style)."),(0,l.yg)("p",null,"If we want to retain the events for 5 days, we need to store 9 million events in the worst case and 3 million in the best case."),(0,l.yg)("p",null,"With 9 million objects in the memory, it is also critical to estimate how much extra memory usage is expected from YuniKorn with different kinds of data structures:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"slice of pointers to si.EventRecord objects ",(0,l.yg)("inlineCode",{parentName:"li"},"[]*si.EventRecord")),(0,l.yg)("li",{parentName:"ul"},"slice of si.EventRecord objects ",(0,l.yg)("inlineCode",{parentName:"li"},"[]si.EventRecord")),(0,l.yg)("li",{parentName:"ul"},"slice of a memory-optimised data type ",(0,l.yg)("inlineCode",{parentName:"li"},"[]internalRecord"))),(0,l.yg)("p",null,"As the name suggests, internalRecord type would only be available inside the ring buffer.\nIt's used together with string interning to save memory caused by repeated strings like IDs (application ID, ask ID, allocation ID, etc.).\nThere are various interning libraries in Go, but removing elements is not possible from them.\nWe need to create our own, so we can track the number of references per string."),(0,l.yg)("p",null,"The following table summarizes memory usage and GC time, depending on how we store the events.\nThe test was executed multiple times to get averages and ranges.\nThe slice was created once, then an index variable was increased for each record, so the built-in ",(0,l.yg)("inlineCode",{parentName:"p"},"append()")," function was not used."),(0,l.yg)("p",null,"The results clearly indicate two things:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"having millions of pointers has negative performance on both the memory usage and GC load"),(0,l.yg)("li",{parentName:"ul"},"batch workloads inherently have a lot of repeated strings, so interning makes a noticeable difference")),(0,l.yg)("p",null,"The GC detects pointers, since it has to follow them to walk the object graph to identify unreferenced objects.\nIf elements in the slice are pointers, then those allocations are scattered all around the heap (bad locality) with header information added by the allocator.\nThis reduces memory access times and increases the amount of the data that is allocated."),(0,l.yg)("p",null,"In the test, the assumption was 100 pods per application.\nIn real life, this value might be different, most likely it's lower.\nThe lower the value, the smaller the advantage of the interning - on the extreme, every application consists of only one pod.\nBut even with only 30 pods per application, it has value - more modest, 20-30% reductions are not negligible when storing millions of elements."),(0,l.yg)("table",null,(0,l.yg)("thead",{parentName:"table"},(0,l.yg)("tr",{parentName:"thead"},(0,l.yg)("th",{parentName:"tr",align:null},"Object type"),(0,l.yg)("th",{parentName:"tr",align:null},"Number of elements"),(0,l.yg)("th",{parentName:"tr",align:null},"Increased memory usage","*"),(0,l.yg)("th",{parentName:"tr",align:null},"GC time","*","*"))),(0,l.yg)("tbody",{parentName:"table"},(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"805 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"85-105 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"437 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"41-55 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"3M"),(0,l.yg)("td",{parentName:"tr",align:null},"211 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"5-16 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"1595 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"160-200 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"856 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"75-110 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"6M"),(0,l.yg)("td",{parentName:"tr",align:null},"404 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"10-30 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]*si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"2380 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"270-320 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]si.EventRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"1280 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"116-150 ms")),(0,l.yg)("tr",{parentName:"tbody"},(0,l.yg)("td",{parentName:"tr",align:null},"[]internalRecord"),(0,l.yg)("td",{parentName:"tr",align:null},"9M"),(0,l.yg)("td",{parentName:"tr",align:null},"593 MiB"),(0,l.yg)("td",{parentName:"tr",align:null},"16-33 ms")))),(0,l.yg)("p",null,(0,l.yg)("em",{parentName:"p"},"*",' "Sys" metrics returned by the Go runtime')),(0,l.yg)("p",null,(0,l.yg)("em",{parentName:"p"},"*","*"," measured by the execution time of ",(0,l.yg)("inlineCode",{parentName:"em"},"runtime.GC()"))),(0,l.yg)("h3",{id:"handling-slow-and-rogue-clients-during-streaming"},"Handling slow and rogue clients during streaming"),(0,l.yg)("p",null,"It's possible to overwhelm YuniKorn with streaming or execute a DoS attack."),(0,l.yg)("p",null,"The first thing we need to address is a rogue client which simply stops reading on the receiver side from the TCP socket.\nEventually writes will block in YuniKorn.\nIf we use channels and per-client goroutines, this should not be an issue - we can always check if the buffer is full using the built-in len() function.\nIf this happens, we can just drop the connection.\nIn some situations, the buffer is expected to be full, for example, when sending history.\nIt's always faster to send out a lot of existing objects, so we can expect the buffer to get full at times.\nThis can be solved by repeatedly checking the rate of writes - if it falls below a certain threshold, then again, we just drop the connection with an error message."),(0,l.yg)("p",null,"We can also limit the number of concurrent streaming connections and historical objects to send, e.g. we simply won't serve requests which would result in sending millions of elements."),(0,l.yg)("p",null,"Note that it's still possible to deny the service from legitimate users because YuniKorn lacks authentication on the REST interface.\nThis will be solved in the future."),(0,l.yg)("h3",{id:"approaches-to-streaming"},"Approaches to streaming"),(0,l.yg)("p",null,"When a client requests a stream of events, it can define how many past events it wants to receive.\nThis is necessary because when YuniKorn starts up, it's not possible to connect immediately.\nIt can be important for certain users to save the state of YuniKorn on an external storage completely from the start."),(0,l.yg)("p",null,"Sending the historical events must be separated from the new events that are constantly occurring in the system, that is, old and current events must not interleave.\nFor example: we want a stream of old and new events, this means:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"We're currently at ",(0,l.yg)("em",{parentName:"li"},"event~n~")),(0,l.yg)("li",{parentName:"ul"},"Send out events from ",(0,l.yg)("em",{parentName:"li"},"event~0~")," all the way up to ",(0,l.yg)("em",{parentName:"li"},"event~n~")),(0,l.yg)("li",{parentName:"ul"},"In the meantime, ",(0,l.yg)("em",{parentName:"li"},"k")," number of events have been generated"),(0,l.yg)("li",{parentName:"ul"},"Therefore, send events up to event",(0,l.yg)("em",{parentName:"li"},"~n+k~")," until we're caught up completely")),(0,l.yg)("h4",{id:"send-history-first-then-stream-new-events"},(0,l.yg)("strong",{parentName:"h4"},"Send history first, then stream new events")),(0,l.yg)("p",null,"The first approach is to retrieve the objects from the ring buffer and start to send them on a channel to the receiver.\nThere is a separate buffered channel for new events with capacity ",(0,l.yg)("em",{parentName:"p"},"localBufferSize"),".\nAs soon as we finish sending the history, we switch to this channel and relay events from it towards the client."),(0,l.yg)("p",null,"We can express this with the following pseudocode:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},"consumerEventLoop(elementCount) {\n local = initLocalEventChannel(localBufferSize)\n // send history\n history := ringbuffer.getHistory(elementCount)\n foreach h : history {\n receiver <- h\n }\n // bridge new events\n foreach e : <-local {\n receiver <- e\n }\n}\n")),(0,l.yg)("p",null,"The publisher logic is:"),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre",className:"language-go"},'publishEvent(event) {\n foreach c : localChannels {\n if len(c) == localBufferSize { // local buffer full?\n closeChan(receiver)\n closeChan(local)\n receiverId = getReceiver(c)\n abort("slow receiver: " + receiverId)\n }\n c <- event\n }\n}\n')),(0,l.yg)("p",null,"Each receiver has its own goroutine.\nThat is, 10 clients means 10 different ",(0,l.yg)("inlineCode",{parentName:"p"},"consumerEventLoop()")," calls running on separate goroutines."),(0,l.yg)("p",null,"To detect slow clients, we simply check the value of ",(0,l.yg)("inlineCode",{parentName:"p"},"len(c)")," whenever we submit the new event.\nIf this equals the capacity of the buffer, we drop the receiver and close the connection."),(0,l.yg)("p",null,"It is possible to send events directly to the receiver channel and skip ",(0,l.yg)("inlineCode",{parentName:"p"},"c")," on the publisher side which is local inside consumerEventLoop.\nThis requires a simple state machine and a temporary slice of new events, since we are not allowed to send directly as long as the history is being transmitted.\nOverall, this is more complicated than the one described above."),(0,l.yg)("p",null,"The simplicity of this method is notable, which is the main advantage: reasoning about its correctness is trivial.\nWe do not need complicated test code and back-and-forth review cycles to ensure that it indeed results in the correct order of events."),(0,l.yg)("p",null,"The biggest question is what happens if channel local becomes full.\nLet's say that localBufferSize is 1000.\nOn a busy cluster with 100 events / second (busiest period), it takes 10 seconds to fill it up completely.\nHowever, nothing stops us from setting the capacity of the buffer to a higher value.\nIf we bump it up to 10000, the client is expected to read the history in 100 seconds.\nOn a decent network, this amount of time should be enough to read the event history, even if it means 100 000 entries from the ring buffer.\nIf a single si.EventRecord results in 300 bytes of JSON text, then it is around 30MiB of data.\nEven if we take serialisation into account, this will not (can not) take minutes."),(0,l.yg)("p",null,"The biggest disadvantage of this method is when a user requests a lot of elements from the history.\nFor example, someone wants to retrieve the last 1M elements.\nIn this case, we need to allocate a slice for 1M entries.\nBased on the measurements, this will generate a sudden spike in the live heap size, around 145-150 MiB. If people repeatedly do this, the memory allocation of YuniKorn can increase very quickly, possibly resulting in a termination of the YuniKorn pod by the kubelet."),(0,l.yg)("h4",{id:"stream-new-events-directly-from-ring-buffer"},(0,l.yg)("strong",{parentName:"h4"},"Stream new events directly from ring buffer")),(0,l.yg)("p",null,"Instead of notifying receivers directly, we just insert the data into the ring buffer.\nFor every client, we create a cursor which points to a given position inside the buffer.\nIf the pointer is behind the tail, it just keeps reading and going forward until it reaches the current tail."),(0,l.yg)("p",null,"Although this method sounds simple on the surface, the implementation is complicated:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"When sending the history, we can't rely on ",(0,l.yg)("inlineCode",{parentName:"li"},"len(buf)")," checking.\nIt is because when we are sending the history, we are always very close to the capacity.\nUnlike the previous solution, we are processing elements from the buffer directly, and we do not bridge two channels.\nIf we do that, we just add further complications.\nTherefore, we have to calculate the sending rate, at least while sending past objects.\nIf the pointer is not making progress (or just very slow), then the tail of the ring buffer will catch up to it, but it can take a very long time."),(0,l.yg)("li",{parentName:"ul"},"In case of multiple cursors, we have to maintain which one is the closest to the tail.\nIf we don't do that, we have to check every cursor when adding elements.\nWe cannot wait for a slow reader to jump to the next element, so we have to invalidate the cursor, then have to calculate which is the nearest to tail again."),(0,l.yg)("li",{parentName:"ul"},"Whenever we reach the last element, we have to block and utilize the well-known wait-notify pattern (",(0,l.yg)("inlineCode",{parentName:"li"},"Cond.Broadcast()")," and ",(0,l.yg)("inlineCode",{parentName:"li"},"Cond.Wait()")," in Go)."),(0,l.yg)("li",{parentName:"ul"},"The overall sending logic is much more complicated: keep reading batches from the ring buffer until we reach the last element, then switch to wait-notify and block.")),(0,l.yg)("p",null,"The advantage of this method is that we don't need large channel buffers to make sure that they don't get filled while sending historical records.\nIf the reader is fast enough, we just keep marshalling ",(0,l.yg)("inlineCode",{parentName:"p"},"si.EventRecord")," objects and bump the pointer to the next element."),(0,l.yg)("div",{className:"footnotes"},(0,l.yg)("hr",{parentName:"div"}),(0,l.yg)("ol",{parentName:"div"},(0,l.yg)("li",{parentName:"ol",id:"fn-1"},(0,l.yg)("a",{parentName:"li",href:"https://pkg.go.dev/strconv#ParseBool"},"https://pkg.go.dev/strconv#ParseBool"),(0,l.yg)("a",{parentName:"li",href:"#fnref-1",className:"footnote-backref"},"\u21a9")),(0,l.yg)("li",{parentName:"ol",id:"fn-2"},(0,l.yg)("a",{parentName:"li",href:"https://pkg.go.dev/strconv#ParseUint"},"https://pkg.go.dev/strconv#ParseUint"),(0,l.yg)("a",{parentName:"li",href:"#fnref-2",className:"footnote-backref"},"\u21a9")))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0c902ed6.9b82eddc.js b/assets/js/0c902ed6.9b82eddc.js deleted file mode 100644 index f16e1a17078..00000000000 --- a/assets/js/0c902ed6.9b82eddc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[54426],{58860:(e,t,a)=>{a.d(t,{xA:()=>p,yg:()=>g});var i=a(37953);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),c=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,p=r(e,["components","mdxType","originalType","parentName"]),u=c(a),d=n,g=u["".concat(l,".").concat(d)]||u[d]||h[d]||s;return a?i.createElement(g,o(o({ref:t},p),{},{components:a})):i.createElement(g,o({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[u]="string"==typeof e?e:n,o[1]=r;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=a(72994),n=(a(37953),a(58860));const s={id:"state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy"},o=void 0,r={unversionedId:"design/state_aware_scheduling",id:"design/state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy",description:"\x3c!--",source:"@site/docs/design/state_aware_scheduling.md",sourceDirName:"design",slug:"/design/state_aware_scheduling",permalink:"/docs/next/design/state_aware_scheduling",draft:!1,tags:[],version:"current",frontMatter:{id:"state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy"},sidebar:"docs",previous:{title:"Resilience",permalink:"/docs/next/design/resilience"},next:{title:"Configuration V2",permalink:"/docs/next/design/config_v2"}},l={},c=[{value:"The problem",id:"the-problem",level:2},{value:"Example issue",id:"example-issue",level:3},{value:"Design",id:"design",level:2},{value:"Design goals",id:"design-goals",level:3},{value:"None goals",id:"none-goals",level:3},{value:"Possible solutions",id:"possible-solutions",level:3},{value:"Algorithm",id:"algorithm",level:3},{value:"Fallback mechanism",id:"fallback-mechanism",level:3},{value:"Example run",id:"example-run",level:3}],p={toc:c},u="wrapper";function h(e){let{components:t,...s}=e;return(0,n.yg)(u,(0,i.A)({},p,s,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"the-problem"},"The problem"),(0,n.yg)("p",null,"A common pattern while processing data is that the application can be divided into multiple stages.\nAnother way to look at this is the fact that processing needs to be kicked off and that the first step is to start a driver or manager for the application.\nLater stages might depend on the previous stages.\nWhen running applications in a size limited environment this could lead to a resource exhaustion when submitting multiple applications at the same time.\nThese first stages might consume all available resources leaving no room for the next stage(s) to start.\nOften this issue is caused by having a high number of applications start simultaneous and trying to get resources in parallel."),(0,n.yg)("h3",{id:"example-issue"},"Example issue"),(0,n.yg)("p",null,"When submitting numerous Spark applications in a short amount of time the drivers will all be started shortly after each other.\nThe drivers consume all available resources in a queue or in the whole cluster.\nAfter starting the drivers they will request resources for the executors.\nSince the queue or cluster has no resources left the executors will not be started.\nThe driver cannot progress.\nThe only way that progress would be made is if and when one of the drivers finishes or fails and frees up resources for executors to be started."),(0,n.yg)("h2",{id:"design"},"Design"),(0,n.yg)("h3",{id:"design-goals"},"Design goals"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"Prevent resource exhaustion by first stage allocations"),(0,n.yg)("li",{parentName:"ol"},"Improve chance for jobs to get minimal required resources over others")),(0,n.yg)("h3",{id:"none-goals"},"None goals"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"This is NOT an implementation of Gang scheduling."),(0,n.yg)("li",{parentName:"ol"},"No change to the currently supported FAIR or FIFO scheduling algorithms"),(0,n.yg)("li",{parentName:"ol"},"Fix resource quota usage outside of the core scheduler for submitted but waiting applications")),(0,n.yg)("h3",{id:"possible-solutions"},"Possible solutions"),(0,n.yg)("p",null,"Other batch schedulers like the YARN schedulers use a limit on the number of simultaneous running applications.\nThey use either resource constraints on the driver or management stage or set a hard limit of the number of applications that can run in a queue.\nThe draw back of that solution is that it does not work well in a cluster that can scale up or down automatically in a cloud environment.\nTo work around that percentage based limits could be set on the consumed resources for the driver or management stage.\nThis does not alleviate the fact that driver or management stages can be of any size, large and or small, which complicates the percentage scenario further as it does not give a predictable behaviour."),(0,n.yg)("p",null,"A different solution would be to assume a specific behaviour of the applications.\nUsing that assumption a limit on the applications could be set based on the state it is in.\nThe spark driver and executor behaviour is the most usual use case.\nThis would provide a way to limit scheduling to existing applications and only drip feed new applications into the list of applications to schedule when there are resources available."),(0,n.yg)("h3",{id:"algorithm"},"Algorithm"),(0,n.yg)("p",null,"The algorithm described here is based on the drip feed of new applications into the applications to schedule based on the states of all applications.\nScheduling is based on the applications in a queue.\nThe algorithm will be applied at a queue level.\nThis is not a cluster wide setup."),(0,n.yg)("p",null,"What we want to achieve is the following behaviour: only schedule one (1) application that is in its early stage(s) (called a starting state) at the same time.\nOnly consider another new application if and when the previous application has transitioned out of the starting state.\nApplications will always be allocated resources on a first in first out basis based on submission time.\nThat means that an application that is newly added and in its starting phase will only get resources if applications in the later stages do not need any resources."),(0,n.yg)("p",null,"This algorithm will be implemented as an application sorting policy on a queue.\nThis allows specific queues to limit parallel application startup while other queues with different work loads can schedule without or with different limitations."),(0,n.yg)("h3",{id:"fallback-mechanism"},"Fallback mechanism"),(0,n.yg)("p",null,"A fallback mechanism has to be built into the algorithm.\nNot all applications will request more than one allocation.\nThe other case that has to be accounted for could be a misbehaving or a slow application.\nHaving an application stuck in the starting state could cause a scheduler livelock and starvation of other applications."),(0,n.yg)("p",null,"The fall back mechanism proposed is as simple as a time limit on the starting state.\nThis means that any application auto progresses out of the starting state.\nThe time limit will be set to five (5) minutes hard coded as a starting point and will not be made configurable."),(0,n.yg)("p",null,"The other fallback mechanism considered was making the number of allocations for the starting state configurable.\nThis option provided a number of issues which made it difficult to implement.\nOne of the main stumbling blocks is the fact that it requires the application submitter to specify the value.\nIt also does not guarantee that the application will leave the starting state either and does not fix the livelock issue.\nIf an application was submitted with five required allocation but due to issues during the run never asked for more than four then the livelock would still occur."),(0,n.yg)("p",null,"Setting a default of zero (0) would also not work as it would bypass the starting state.\nIt would make the sorting policy an opt-in instead of an opt-out.\nSetting a default of one (1) does not give us much enhancement to what we currently propose.\nIt makes the sorting policy an opt-out but does not give the cluster administrator any control over the scheduling behaviour.\nWeighing those against each other the proposal is to not make this configurable."),(0,n.yg)("h3",{id:"example-run"},"Example run"),(0,n.yg)("p",null,"Using Spark applications as an example: a new application can only be scheduled if the previous application has at least one (1) executor allocated."),(0,n.yg)("p",null,(0,n.yg)("img",{alt:"images",src:a(1302).A,width:"1344",height:"820"})),(0,n.yg)("p",null,"Assume we have the following Spark apps: App1 & App2 as in the diagram above. The applications were submitted in that order: App1 first, then App2. They were both submitted to the same queue."),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"Both applications are in the queue waiting for the first allocation: accepted by the scheduler. App1 has requested driver D1 and App2 has requested driver D2."),(0,n.yg)("li",{parentName:"ol"},"The scheduler sorts the application and allows 1 accepted application to be scheduled (no starting applications yet): App1 as the oldest applications with an outstanding request is scheduled.",(0,n.yg)("br",{parentName:"li"}),"App1 is allocated its driver (D1) and progresses to starting.",(0,n.yg)("br",{parentName:"li"}),"App2 request for a driver is ignored as the scheduler is starting App1 (only 1 application in starting or accepted state is scheduled)."),(0,n.yg)("li",{parentName:"ol"},"App1 requests executors E11 and E12. The scheduler assigns E11 and E12. At this point the application state changes to running when it has at least 1 executor allocated."),(0,n.yg)("li",{parentName:"ol"},"App2 has been waiting to get the driver allocated. Since there are no applications in a starting state the scheduler looks at App2 which is in an accepted state. App2 moves from the accepted state to starting when the driver is allocated."),(0,n.yg)("li",{parentName:"ol"},"App2 requests its executor E21. The application state changes to running when E21 is allocated.")),(0,n.yg)("p",null,"This process would repeat itself for any new application submitted."))}h.isMDXComponent=!0},1302:(e,t,a)=>{a.d(t,{A:()=>i});const i=a.p+"assets/images/fifo-state-example-294dbf22ea35a750c8ad768c8760929d.png"}}]); \ No newline at end of file diff --git a/assets/js/1582f434.2eef43b5.js b/assets/js/1582f434.2eef43b5.js deleted file mode 100644 index a1fde382698..00000000000 --- a/assets/js/1582f434.2eef43b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[64660],{58860:(e,t,r)=>{r.d(t,{xA:()=>l,yg:()=>d});var a=r(37953);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var u=a.createContext({}),c=function(e){var t=a.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=c(e.components);return a.createElement(u.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(r),h=n,d=p["".concat(u,".").concat(h)]||p[h]||g[h]||o;return r?a.createElement(d,i(i({ref:t},l),{},{components:r})):a.createElement(d,i({ref:t},l))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=h;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:n,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=r(72994),n=(r(37953),r(58860));const o={id:"user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking"},i=void 0,s={unversionedId:"design/user_based_resource_usage_tracking",id:"design/user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking",description:"\x3c!--",source:"@site/docs/design/user_group_manager.md",sourceDirName:"design",slug:"/design/user_based_resource_usage_tracking",permalink:"/docs/next/design/user_based_resource_usage_tracking",draft:!1,tags:[],version:"current",frontMatter:{id:"user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking"},sidebar:"docs",previous:{title:"User/Group handling and lookup design",permalink:"/docs/next/design/user_group"},next:{title:"User Based Quota Enforcement",permalink:"/docs/next/design/user_group_resource_usage_enforcement"}},u={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:2},{value:"Non Goals",id:"non-goals",level:2},{value:"Tracking definitions",id:"tracking-definitions",level:2},{value:"User vs Group tracking",id:"user-vs-group-tracking",level:3},{value:"Group limitations",id:"group-limitations",level:3},{value:"Cluster or queue based tracking",id:"cluster-or-queue-based-tracking",level:3},{value:"Application tracking",id:"application-tracking",level:2},{value:"Running state entry",id:"running-state-entry",level:3},{value:"Running state exit",id:"running-state-exit",level:3},{value:"Resource usage tracking",id:"resource-usage-tracking",level:2},{value:"Scheduler transparency",id:"scheduler-transparency",level:2},{value:"User Group Manager (UGM)",id:"user-group-manager-ugm",level:2},{value:"UserGroup cache impact",id:"usergroup-cache-impact",level:3},{value:"Tracking structure",id:"tracking-structure",level:3},{value:"Tracker interface",id:"tracker-interface",level:3},{value:"User tracking",id:"user-tracking",level:3},{value:"Group tracking",id:"group-tracking",level:3},{value:"Queue tracking",id:"queue-tracking",level:3},{value:"Update consistency",id:"update-consistency",level:3},{value:"Exposure of usage tracking",id:"exposure-of-usage-tracking",level:3}],l={toc:c},p="wrapper";function g(e){let{components:t,...r}=e;return(0,n.yg)(p,(0,a.A)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"introduction"},"Introduction"),(0,n.yg)("p",null,"Tracking resource allocation usage is currently limited to a queue. An application, which owns the allocation, is the source of that resource usage. All applications that are part of the queue will count towards the resource usage of the queue. A queue could also have a resource usage quota set. The queue\u2019s resource quota is enforced during the scheduling cycle."),(0,n.yg)("p",null,"An application is always owned by a user/group. One user/group could own applications in one or more queues. Like a queue a user/group could have a limit set. A limit can specify a resource usage quota, and an application usage limit. Tracking these usages per user/group is currently not implemented and is covered as part of this design."),(0,n.yg)("h2",{id:"goals"},"Goals"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"Specify tracking usage in relation to the following objects:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"users"),(0,n.yg)("li",{parentName:"ul"},"applications"),(0,n.yg)("li",{parentName:"ul"},"queues"))),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"An interface to define how to track running applications:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"Read a user/group running applications"),(0,n.yg)("li",{parentName:"ul"},"Increase a user/group running applications *)"),(0,n.yg)("li",{parentName:"ul"},"Decrease a user/group running applications"))),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"An interface to define how to track usage:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"Read a user/group resource usage"),(0,n.yg)("li",{parentName:"ul"},"Increase a user/group resource usage *)"),(0,n.yg)("li",{parentName:"ul"},"Decrease a user/group resource usage")),(0,n.yg)("p",{parentName:"li"},"*) This call could be extended for enforcement later.")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"Expose user/group tracked information through REST API"))),(0,n.yg)("h2",{id:"non-goals"},"Non Goals"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"User and group retrieval is part of the k8shim which is out of scope"),(0,n.yg)("li",{parentName:"ul"},"Exposing usage as a metric into prometheus"),(0,n.yg)("li",{parentName:"ul"},"Specify enforcement rules"),(0,n.yg)("li",{parentName:"ul"},"Implementation of enforcement"),(0,n.yg)("li",{parentName:"ul"},"Interface definition to allow enforcement")),(0,n.yg)("h2",{id:"tracking-definitions"},"Tracking definitions"),(0,n.yg)("h3",{id:"user-vs-group-tracking"},"User vs Group tracking"),(0,n.yg)("p",null,"Tracking is based on the ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object defined in the core scheduler. User and group information is retrieved by the shim and communicated via the ",(0,n.yg)("em",{parentName:"p"},"UserGroupInformation")," object as defined in the scheduler interface. A ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object contains:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"user (exactly 1)"),(0,n.yg)("li",{parentName:"ul"},"groups (0 or more)")),(0,n.yg)("p",null,"Limits can be configured for both users and groups at the same time in the same queue. So, in the case of users for which no limit has been configured explicitly but group (to which the user belongs to) limits have configured works based on the group limits configuration. In case of users for which a limit has been configured explicitly works based on its own configured limits irrespective of whether configuration has been set for the corresponding group (to which the user belongs to) or not. In other words, user limit settings always have the higher precedence when group limit settings have been configured too."),(0,n.yg)("p",null,'"*" is also allowed for both users and groups limit configuration. In this case, any user or group needs to go through enforcement checks to ensure limit settings are being honoured properly. However, the tracker does not need to track the wildcard user as a specific user or group is already being tracked during their activities.'),(0,n.yg)("h3",{id:"group-limitations"},"Group limitations"),(0,n.yg)("p",null,"Users can belong to zero, one or multiple groups. In some systems, like unix, a concept of a primary group exists. This concept is not universal and there is no consistent definition of a primary group either. If the system does not define a primary group how would we distinguish between the groups?"),(0,n.yg)("p",null,"In the case the user is a member of multiple groups the assignment of usage to a group also becomes problematic. The decision which group to assign the usage to becomes arbitrary. As an example consider a user with multiple groups assigned. Joe has groups dev and test assigned. When an application is started does that application count towards the limits for the dev group or against the limits for the test group or both?"),(0,n.yg)("p",null,"The ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object contains a slice, list or array, of groups which has a fixed order from the moment of creation. The group resolution configured might not guarantee an ordering which means we cannot rely on the order in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," to be stable. A stable and pre-defined way of choosing a group to track usage against must be defined."),(0,n.yg)("p",null,"The first point to define is that tracking can only occur against zero (0) or one (1) group. Usage can never be tracked against multiple groups. If a user is a member of multiple groups, a group is selected when the first usage is registered for the application. The group selected out of the list of groups in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object to track against is based on the hierarchical queue limit configuration. The hierarchy is considered bottom up, starting from the leaf up to the root. The first group that is specified in the queue hierarchy for limiting usage that matches a group in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object is selected for that application."),(0,n.yg)("p",null,"If no group limits are defined, in the hierarchy, usage is not tracked for a group. If no groups are defined in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object no usage will be tracked against a group."),(0,n.yg)("p",null,"The tracker considers only the group received as part of the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object at the time of first usage registration for the application in the tracker. In case of group changes while the user\u2019s application is actively being tracked, the tracker does not consider the group change. However, If the user submits a new application, the most current group information at that point in time will be used."),(0,n.yg)("p",null,"Until there is full support for groups in the k8shim, group tracking will be limited. No groups are passed by the k8shim to the core. This results in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object in the current implementation to always have only one group. The group name will be the same as the username. We also have excluded configuration processing for the tracking. For the current tracking implementation as described in the document these limitations will result in the user and group linked to the user to track the same usage."),(0,n.yg)("h3",{id:"cluster-or-queue-based-tracking"},"Cluster or queue based tracking"),(0,n.yg)("p",null,"Tracking user usage will be based on the usage per queue. The full hierarchy of the queue will be tracked. We should not just track the leaf or root of the hierarchy. The overall cluster usage is the same as the usage of the root queue. Cluster level usage does not need separate tracking."),(0,n.yg)("p",null,"The overhead of tracking per queue should be really limited. In most cases a user will run their workloads in a specific queue. Deeply nested queues do also add overhead to the tracking. During testing the impact of workload spread and or deep nesting needs to be assessed. If needed this can be called out in the documentation."),(0,n.yg)("p",null,"We also need to take into account that multiple members of a group could be using different queues in the hierarchy. If tracking usage would be limited to the leaf level, aggregating group usage becomes more difficult and loses transparency."),(0,n.yg)("p",null,"The documentation around limits, part of the enforcement, reference different limits at different levels for users or groups. Tracking at just the leaf or root level could break that functionality. The design should support the current documented features. If during enforcement design a different decision is made then the tracking is not the deciding factor."),(0,n.yg)("h2",{id:"application-tracking"},"Application tracking"),(0,n.yg)("p",null,"Applications go through a number of states within the core scheduler. Allocations linked to applications are the triggers for application state changes. From a tracking perspective we need to define what is considered a running application."),(0,n.yg)("p",null,"Since placeholders and placeholder timeout can play a role in state changes the implementation of the running application tracking must take into account these cases:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"no gang defined"),(0,n.yg)("li",{parentName:"ul"},"gang defined, all or some placeholders replaced"),(0,n.yg)("li",{parentName:"ul"},'gang style "soft" defined, all placeholders time out'),(0,n.yg)("li",{parentName:"ul"},'gang style "hard" defined, all placeholders time out')),(0,n.yg)("h3",{id:"running-state-entry"},"Running state entry"),(0,n.yg)("p",null,"The application when submitted and placed into a queue is in the ",(0,n.yg)("em",{parentName:"p"},"New")," state. At this point there is no allocation or pending request present on the application. After one or more requests, ",(0,n.yg)("em",{parentName:"p"},"AllocationAsks"),", are added the application moves into an ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state. The ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state is exited when the first ",(0,n.yg)("em",{parentName:"p"},"Allocation")," is added to the application. The application then transitions into the Starting state."),(0,n.yg)("p",null,"At this point a resource quota would be used by the application and the application should be considered as running from a tracking perspective. This means that the addition of the first ",(0,n.yg)("em",{parentName:"p"},"Allocation")," onto the application also must be the trigger point for the increase of the running applications. This trigger point for tracking is when the application is in the ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state. This is also the point at which the group for the usage tracking needs to be set as described in the ",(0,n.yg)("a",{parentName:"p",href:"#group-limitations"},"group limitations"),"."),(0,n.yg)("p",null,"Note that currently, the application state transition code block in application",(0,n.yg)("em",{parentName:"p"},"state.go updates the application running queue metrics when the application enters _Running")," state. The metric must be updated to be consistent with the above definition of a running application. Linking this back to a state transition the entry into the Starting state should be used."),(0,n.yg)("h3",{id:"running-state-exit"},"Running state exit"),(0,n.yg)("p",null,"An application should be considered running as long as at least one allocation is assigned to the application. The removal of the last allocation should decrease the number of running applications. However, we also need to consider the pending requests."),(0,n.yg)("p",null,"As part of the application states the application enters into a ",(0,n.yg)("em",{parentName:"p"},"Completing")," state when the last allocation is removed and there are no pending requests. This automatically progresses into the ",(0,n.yg)("em",{parentName:"p"},"Completed")," state if nothing changes for the application. Applications going into the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state all have no allocations left and pending requests are considered. The entry of the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state thus could be used as a point for triggering the decrease of the running application count."),(0,n.yg)("p",null,"However there are circumstances that the application goes from the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state back into a ",(0,n.yg)("em",{parentName:"p"},"Running")," state. This is linked to auto restart of a pod by Kubernetes. This case must be handled."),(0,n.yg)("p",null,"A last case that needs to be considered is an application that fails. If an application fails it moves into the Failing state. The application does not enter ",(0,n.yg)("em",{parentName:"p"},"Completing"),' but could have incremented the running applications. A failure could be triggered by the gang scheduling style "hard" or the removal of a partition.'),(0,n.yg)("h2",{id:"resource-usage-tracking"},"Resource usage tracking"),(0,n.yg)("p",null,"Resource usage is tracked simply based on the addition or removal of an allocation."),(0,n.yg)("p",null,"Removal of an allocation is an out-of-band action. The shim notifies the core scheduler that an allocation no longer exists and the core updates the tracking based on that removal. If an allocation is preempted the core initiates the removal but still gets notified by the shim that the removal has occurred. Until the confirmation of the shim is received no tracking updates must be created."),(0,n.yg)("p",null,"The replacement of a placeholder by the real allocation for gang scheduling follows a similar concept. However, in that case there is a possibility that there is a discrepancy between the placeholder size and the real allocation. See ",(0,n.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-982"},"YUNIKORN-982")," for more detailed information on this issue. The changes that fixed the accounting for the queues and nodes also need to be taken into account for user based resource tracking."),(0,n.yg)("p",null,"Adding a new allocation to an application triggers the update of the tracked resources for the user and or group as described in the ",(0,n.yg)("a",{parentName:"p",href:"#group-limitations"},"group limitations"),". Enforcement is not a goal of the design document but the enforcement implementation needs to be taken into account. The point to add the resource usage must line up with the point that the queue structure is currently updated and the queue quotas are enforced."),(0,n.yg)("p",null,"The order of the updates: queue structure first then user or user first then queue structure is debatable. The current proposal is to implement the following:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"Update user and group based usage"),(0,n.yg)("li",{parentName:"ul"},"Queue quota enforcement and update"),(0,n.yg)("li",{parentName:"ul"},"If the queue enforcement fails, roll back the user and group based update.")),(0,n.yg)("h2",{id:"scheduler-transparency"},"Scheduler transparency"),(0,n.yg)("p",null,"Resource usage tracking is based on the allocated resource, and linked to the application\u2019s queue path and the application\u2019s ",(0,n.yg)("em",{parentName:"p"},"user")," field. Application tracking is a simple count of the applications, and is linked to the application\u2019s queue path and the application\u2019s user field.\nAs an extension on this we could consider adding the ",(0,n.yg)("em",{parentName:"p"},"applicationID")," into the tracking of the running applications to help with troubleshooting. This is part of the current proposal. The proposal is to not link the running application tracking to the applicationID."),(0,n.yg)("p",null,"The user field of an application is the earlier mentioned ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object and has all the identifying details needed to track the usage."),(0,n.yg)("p",null,"From the schedulers perspective there should be no special setup needed. The tracking should always work without the need to pre-create a user, group or queue based entry. This means that the tracking cannot fail even if the user or group has no enforcement linked to it and does not exist in the tracker."),(0,n.yg)("p",null,"In summary the tracker must implement:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"User and or group creation on the fly."),(0,n.yg)("li",{parentName:"ul"},"Auto cleanup of tracking information no longer needed."),(0,n.yg)("li",{parentName:"ul"},"Configuration processing needed for enforcement.")),(0,n.yg)("h2",{id:"user-group-manager-ugm"},"User Group Manager (UGM)"),(0,n.yg)("p",null,"Tracking all the resources will be part of a new self-contained module in the scheduler. This means that there must be no imports from the ",(0,n.yg)("inlineCode",{parentName:"p"},"scheduler.objects")," package. This will allow us to run the tracker separately and push updates, if needed, into a background processing queue."),(0,n.yg)("p",null,"There will be one user group manager created per partition as part of the partition creation process. There will be no tracking of user quotas over a partition boundary."),(0,n.yg)("p",null,"The new self-contained module, user group manager contains all specifications and code for tracking and can be extended in the future to include enforcement code."),(0,n.yg)("p",null,"Tracking the resources and application count for all users occurs from startup. This happens irrespective of whether enforcement is configured for the user or group. By starting tracking independently of the enforcement changes in enforcement will always have a consistent view of the resources tracked at least at a user level. Recovery must be tested in combination with the tracking code."),(0,n.yg)("p",null,"Storing data in the user group manager is based on the ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," structure content. The built-in ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache")," resolution cannot guarantee that the same object is returned for the same user each time."),(0,n.yg)("h3",{id:"usergroup-cache-impact"},"UserGroup cache impact"),(0,n.yg)("p",null,"The concept of a stable user entry in the cache is not currently present in the ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache"),". This concept will most likely also not be possible based on the fact that group resolution does not guarantee ordering. Based on the assumption that we cannot guarantee group ordering for all group resolutions that are possible the tracking will not rely on it."),(0,n.yg)("p",null,"Currently, ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache")," holds the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object entry only for the cache period. This is either 300 seconds for a positive resolution or 30 seconds for a negative resolution. After this cache time the entry will be deleted as part of the cache cleanup/expiration process. If the same user submits a second application after the expiry, a new ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object will be created and stored in the cache. The ",(0,n.yg)("em",{parentName:"p"},"UserGroup"),' object has a property "resolved", which holds a timestamp at which the user group resolution has been executed for the first time. The cache cleaner wakes up after every 60 seconds and deletes all entries whose "resolved" timestamp is older than the cache timeout.'),(0,n.yg)("p",null,"Other internal changes might be needed to make sure all ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," objects are cached correctly and returned as expected internally in the cache. These are left as implementation details for the cache changes."),(0,n.yg)("h3",{id:"tracking-structure"},"Tracking structure"),(0,n.yg)("p",null,"The user group Manager must be able to track usage for users and groups. Users are the primary access point for all tracking. The user group Manager structure will implement the ",(0,n.yg)("a",{parentName:"p",href:"#tracker-interface"},"tracker interface"),"."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype Manager struct {\n users map[string]*userTracker\n groups map[string]*groupTracker\n\n sync.RWMutex\n}\n(m *Manager) checkAppGroup(queuePath, applicationID string, user *security.UserGroup)\n")),(0,n.yg)("p",null,"All objects in the user group manager will be managed internally. Creation of user and or group tracker objects is based on the request to track usage. The objects are added to one of the two structures in the user group manager. Adding user or group objects can only be triggered by an increase of tracked resources. The creation of the user and or group tracker objects is handled by the user group manager. The user group manager is also responsible for setting the usage information for the queue hierarchy directly after creation."),(0,n.yg)("p",null,"The resolution of the group that the usage is tracked against for an application is handled by the user group Manager via the checkAppGroup. As part of an increase of resource usage the Manager will check if the application is already tracked for the user. If the application is already tracked nothing changes. If the application is not tracked the manager will resolve the group to track against and update the userTracker object. If there is no active tracker registered for the group a new groupTracker object will be created and initialised as required."),(0,n.yg)("p",null,"Removal of user or group objects can only be triggered after a decrease of tracked resources has removed the last usage. Usage tracked for a user must be zero. For group tracker objects the application reference count must be zero.\nRemoval of the user and or group tracker objects is done periodically. This cleanup must be ",(0,n.yg)("inlineCode",{parentName:"p"},"go routine")," safe. Updates to either map could be triggered from different routines, scheduler allocation processing or a release of an allocation by a shim."),(0,n.yg)("h3",{id:"tracker-interface"},"Tracker interface"),(0,n.yg)("p",null,"The interface describes the functions that will be exposed by the user group manager. The other scheduler components can rely on the functions defined in the interface to be available to increase, decrease applications and or resource usage and get the tracked resources."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype Tracker interface {\n GetUserResources(user *security.UserGroup) *Resource\n GetGroupResources(group string) *Resource\n\n GetUsersResources() []*userTracker\n GetGroupsResources() []*groupTracker\n\n IncreaseTrackedResource(queuePath, applicationID string, usage *Resource, user *security.UserGroup) error\n DecreaseTrackedResource(queuePath, applicationID string, usage *Resource, removeApp bool, user *security.UserGroup) error\n}\n")),(0,n.yg)("p",null,"The ",(0,n.yg)("em",{parentName:"p"},"IncreaseTrackedResource()")," and ",(0,n.yg)("em",{parentName:"p"},"DecreaseTrackedResource()")," calls will implement the tracking data updates. The Get* calls are providing safe access to the tracked data to be used as part of exposing the data in the REST interface. See ",(0,n.yg)("a",{parentName:"p",href:"#exposure-of-usage-tracking"},"exposure of usage tracking")," for more detail."),(0,n.yg)("p",null,"Applications are added automatically during the call to increase the tracked resources. The first time the applicationID is encountered the structures are updated accordingly and tracking starts. The removal of the application is triggered by leaving the ",(0,n.yg)("a",{parentName:"p",href:"#running-state-exit"},"running state"),", this is equivalent to the removal of the last usage and must also set the removeApp flag to true."),(0,n.yg)("p",null,"Calling ",(0,n.yg)("em",{parentName:"p"},"IncreaseTrackedResource()")," and ",(0,n.yg)("em",{parentName:"p"},"DecreaseTrackedResource()")," with empty or nil parameters is not allowed and will return an error to be handled by the caller. The ",(0,n.yg)("em",{parentName:"p"},"GetUserResource")," and ",(0,n.yg)("em",{parentName:"p"},"GetGroupResource")," calls can return a ",(0,n.yg)("em",{parentName:"p"},"nil")," Resource value. The ",(0,n.yg)("em",{parentName:"p"},"GetUsersResource")," and ",(0,n.yg)("em",{parentName:"p"},"GetGroupsResource")," calls can return an empty slice."),(0,n.yg)("h3",{id:"user-tracking"},"User tracking"),(0,n.yg)("p",null,"The userTracker contains all tracked usage information for a user. Changes for all usage, even the group usage, are part of the change that gets triggered on the user object."),(0,n.yg)("p",null,"The userTracker object contains a reference map to the usage for each application that is tracked linking it to the groupTracker object for the specific application. Multiple applications can be tracked against the same groupTracker object."),(0,n.yg)("p",null,"The group references will be set for each application when usage is added for an application and is not mutable. The existence of a groupTracker for the application can be checked by calling ",(0,n.yg)("em",{parentName:"p"},"hasGroupForApp")," on the userTracker object. It returns true in case the application ID exists in the group mapping, false if it does not. The return value is only based on the existence of the applicationID as the key, not on the value it references."),(0,n.yg)("p",null,"The groupTracker can be set in the userTracker object by calling ",(0,n.yg)("em",{parentName:"p"},"setGroupForApp"),". If the applicationID already exists, the call to set the groupTracker reference is a noop, nothing will change. The reference cannot be changed after it is set. The groupTracker reference can be nil. In the case of a nil reference, no tracking for that application against a group is performed. Even a nil reference cannot be replaced."),(0,n.yg)("p",null,"An increase or decrease of the resources tracked for the user requires the applicationID to be set to a non-empty value. On removal of the last allocation for the application the group reference will be removed from the userTracker object. To remove a running application from the userTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true. Removal of the groupTracker reference can only occur as part of a ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call."),(0,n.yg)("p",null,"If there are no applications left in the group references the object will be removed by the cleanup run from the user group manager. This will also mean that there is no usage tracked anymore by the referenced queueTracker object."),(0,n.yg)("p",null,"The usage per queue is stored in a queue structure specific for this user. The queueTracker object provides a hierarchical structure. This structure starts at the root of the queue hierarchy and only contains child queues for which a usage is being tracked. The hierarchy must be updated, add or delete of child entries, as part of the updates that are processed."),(0,n.yg)("p",null,"The creation of the root queueTracker is part of the creating a new userTracker object."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype userTracker struct {\n userName string\n group map[string]*groupTracker\n queue *queueTracker\n \n sync.RWMutex\n}\n\nnewUserTracker(queuePath string, user *security.UserGroup) *userTracker\n\n(ut *userTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(ut *userTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n(ut *userTracker) hasGroupForApp(applicationID string) bool\n(ut *userTracker) setGroupForApp(applicationID string, groupTrack *groupTracker)\n")),(0,n.yg)("h3",{id:"group-tracking"},"Group tracking"),(0,n.yg)("p",null,"The groupTracker contains all tracked usage information for a group. This object can be shared by multiple users for one or more applications. It adds the applications that are tracked for this specific group automatically to the list. For this it expects an applicationID to be set to a non-empty value for each ",(0,n.yg)("em",{parentName:"p"},"increaseResource")," call."),(0,n.yg)("p",null,"To simply decrease the resources tracked for the group the applicationID could be empty. On removal of the last allocation for the application the application will be removed from the groupTracker object. To remove a running application from the groupTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true."),(0,n.yg)("p",null,"If there are no entries left in the applications tracked in the groupTracker the object will be removed by the cleanup run from the user group manager. This will also mean that there is no usage tracked any more by the referenced queueTracker object."),(0,n.yg)("p",null,"The usage per queue is stored in a queue structure specific for this group. The queueTracker object provides a hierarchical structure. This structure starts at the root of the queue hierarchy and only contains child queues for which a usage is being tracked. The hierarchy must be updated, add or delete of child entries, as part of the updates that are processed."),(0,n.yg)("p",null,"The creation of the root queueTracker is part of the creating a new groupTracker object."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype groupTracker struct {\n groupName string\n applications map[string]bool\n queue *queueTracker\n \n sync.RWMutex\n}\n\nnewGroupTracker(queuePath string, group string) *groupTracker\n\n(gt *groupTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(gt *groupTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n")),(0,n.yg)("h3",{id:"queue-tracking"},"Queue tracking"),(0,n.yg)("p",null,"The queueTracker acts as a base for both user and group tracking. It provides the actual location for the tracked usage.The top of the structure, which is referenced from the userTracker or groupTracker objects, contains the root queue usage. The queueTracker is only referenced by one userTracker or one groupTracker object and must not be shared. This means that we should not require any locking within the queueTracker object."),(0,n.yg)("p",null,"The queue hierarchy below the root, for which a usage is registered, is part of the childQueues. Each part of the full queue path creates a new level of objects. This structure shows a sparse hierarchical queue structure. It may not represent the full queue structure as known in the scheduler."),(0,n.yg)("p",null,'The creation of the root queueTracker returns a plain object without usage set and a fixed queueName of "root". The usage should then be updated by a call to ',(0,n.yg)("em",{parentName:"p"},"increaseResource"),". The call must handle the recursive creation of the queue path as given. It expects an applicationID to be set to a non-empty value for each call."),(0,n.yg)("p",null,"To simply decrease the resources tracked for the queue the applicationID can be empty. On removal of the last allocation for the application the application will be removed from the queueTracker. To remove a running application from the queueTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype queueTracker struct {\n queueName string\n resourceUsage *Resource\n runningApplications map[string]boolean\n\n childQueues map[string]*queueTracker\n}\n\nnewQueueTracker() *queueTracker\n\n(qt *queueTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(qt *queueTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n")),(0,n.yg)("h3",{id:"update-consistency"},"Update consistency"),(0,n.yg)("p",null,"All changes are triggered against a userTracker object. Since enforcement of a quota is out of scope of this design we can ignore update failures due to quota exhaustion. There is no requirement or possibility that updates need to be rolled back."),(0,n.yg)("p",null,"Usage updates can be triggered from two points: allocation by the scheduler and releases by a shim. Allocations as well as releases need to update both user and group usage information. We must guarantee that for both the full hierarchy is changed or neither are changed."),(0,n.yg)("p",null,"The releases are also processed asynchronously from the scheduling cycle. This means that we have to be able to guarantee that the increases and decreases are applied consistently to both objects also. Locking of the objects to serialise changes must be in place to support this."),(0,n.yg)("p",null,"The other point is the update ordering and locking. The increase and decrease processing must follow the same order. Both must update the userTracker and related groupTracker objects in the same order. This is a requirement to prevent the processing of being able to deadlock while updating the same user for a simultaneous increase and decrease."),(0,n.yg)("p",null,"For groupTracker updates that originate from two different users the locking of the groupTracker object is required. One of the two updates will be able to proceed while the other waits for the update to finalise."),(0,n.yg)("p",null,"A final consideration is the consistency of two updates on the same object that follow each other closely. If the first update removes all existing usage the userTracker or groupTracker object is cleared for removal. While the update is in progress a second update comes in to add a new usage to the same object. The resolution of the userTracker in the user group manager has finished. The code has a reference to the object. Processing is waiting to lock the userTracker object. This point could cause the object to become unlinked and usage tracking information to be lost. The implementation needs to prevent this race condition."),(0,n.yg)("h3",{id:"exposure-of-usage-tracking"},"Exposure of usage tracking"),(0,n.yg)("p",null,"The usage tracking information that is part of the user group manager must be exposed for external consumption. All our current information is exposed via a REST call."),(0,n.yg)("p",null,"Based on the current REST api definition for other object the proposal is to expose the following new endpoints:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"/ws/v1/partition/{partitionName}/usage/users"),(0,n.yg)("li",{parentName:"ul"},"/ws/v1/partition/{partitionName}/usage/groups")),(0,n.yg)("p",null,"For both endpoints we expose the full queue hierarchy. As an example below the approximate output for the user's endpoint for one user:"),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "userName": "user1",\n "groups": {\n "app2": "tester"\n },\n "queues":\n {\n "queuename": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuename": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuename": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,n.yg)("p",null,"An example below the approximate output for the groups endpoint for one group:"),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "groupName" : "tester",\n "applications": ["app2"],\n "queues":\n {\n "queuename": "root",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app2"],\n "children": [\n {\n "queuename": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app2"],\n "children": []\n }\n ]\n }\n }\n]\n')))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1582f434.fa10d125.js b/assets/js/1582f434.fa10d125.js new file mode 100644 index 00000000000..4fc13f56c94 --- /dev/null +++ b/assets/js/1582f434.fa10d125.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[64660],{58860:(e,t,r)=>{r.d(t,{xA:()=>l,yg:()=>d});var a=r(37953);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var u=a.createContext({}),c=function(e){var t=a.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=c(e.components);return a.createElement(u.Provider,{value:t},e.children)},p="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=c(r),h=n,d=p["".concat(u,".").concat(h)]||p[h]||g[h]||o;return r?a.createElement(d,i(i({ref:t},l),{},{components:r})):a.createElement(d,i({ref:t},l))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=h;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[p]="string"==typeof e?e:n,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=r(72994),n=(r(37953),r(58860));const o={id:"user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking"},i=void 0,s={unversionedId:"design/user_based_resource_usage_tracking",id:"design/user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking",description:"\x3c!--",source:"@site/docs/design/user_group_manager.md",sourceDirName:"design",slug:"/design/user_based_resource_usage_tracking",permalink:"/docs/next/design/user_based_resource_usage_tracking",draft:!1,tags:[],version:"current",frontMatter:{id:"user_based_resource_usage_tracking",title:"User Based Resource Usage Tracking"},sidebar:"docs",previous:{title:"User/Group handling and lookup design",permalink:"/docs/next/design/user_group"},next:{title:"User Based Quota Enforcement",permalink:"/docs/next/design/user_group_resource_usage_enforcement"}},u={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:2},{value:"Non Goals",id:"non-goals",level:2},{value:"Tracking definitions",id:"tracking-definitions",level:2},{value:"User vs Group tracking",id:"user-vs-group-tracking",level:3},{value:"Group limitations",id:"group-limitations",level:3},{value:"Cluster or queue based tracking",id:"cluster-or-queue-based-tracking",level:3},{value:"Application tracking",id:"application-tracking",level:2},{value:"Running state entry",id:"running-state-entry",level:3},{value:"Running state exit",id:"running-state-exit",level:3},{value:"Resource usage tracking",id:"resource-usage-tracking",level:2},{value:"Scheduler transparency",id:"scheduler-transparency",level:2},{value:"User Group Manager (UGM)",id:"user-group-manager-ugm",level:2},{value:"UserGroup cache impact",id:"usergroup-cache-impact",level:3},{value:"Tracking structure",id:"tracking-structure",level:3},{value:"Tracker interface",id:"tracker-interface",level:3},{value:"User tracking",id:"user-tracking",level:3},{value:"Group tracking",id:"group-tracking",level:3},{value:"Queue tracking",id:"queue-tracking",level:3},{value:"Update consistency",id:"update-consistency",level:3},{value:"Exposure of usage tracking",id:"exposure-of-usage-tracking",level:3}],l={toc:c},p="wrapper";function g(e){let{components:t,...r}=e;return(0,n.yg)(p,(0,a.A)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"introduction"},"Introduction"),(0,n.yg)("p",null,"Tracking resource allocation usage is currently limited to a queue. An application, which owns the allocation, is the source of that resource usage. All applications that are part of the queue will count towards the resource usage of the queue. A queue could also have a resource usage quota set. The queue\u2019s resource quota is enforced during the scheduling cycle."),(0,n.yg)("p",null,"An application is always owned by a user/group. One user/group could own applications in one or more queues. Like a queue a user/group could have a limit set. A limit can specify a resource usage quota, and an application usage limit. Tracking these usages per user/group is currently not implemented and is covered as part of this design."),(0,n.yg)("h2",{id:"goals"},"Goals"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"Specify tracking usage in relation to the following objects:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"users"),(0,n.yg)("li",{parentName:"ul"},"applications"),(0,n.yg)("li",{parentName:"ul"},"queues"))),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"An interface to define how to track running applications:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"Read a user/group running applications"),(0,n.yg)("li",{parentName:"ul"},"Increase a user/group running applications *)"),(0,n.yg)("li",{parentName:"ul"},"Decrease a user/group running applications"))),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"An interface to define how to track usage:"),(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"Read a user/group resource usage"),(0,n.yg)("li",{parentName:"ul"},"Increase a user/group resource usage *)"),(0,n.yg)("li",{parentName:"ul"},"Decrease a user/group resource usage")),(0,n.yg)("p",{parentName:"li"},"*) This call could be extended for enforcement later.")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"Expose user/group tracked information through REST API"))),(0,n.yg)("h2",{id:"non-goals"},"Non Goals"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"User and group retrieval is part of the k8shim which is out of scope"),(0,n.yg)("li",{parentName:"ul"},"Exposing usage as a metric into prometheus"),(0,n.yg)("li",{parentName:"ul"},"Specify enforcement rules"),(0,n.yg)("li",{parentName:"ul"},"Implementation of enforcement"),(0,n.yg)("li",{parentName:"ul"},"Interface definition to allow enforcement")),(0,n.yg)("h2",{id:"tracking-definitions"},"Tracking definitions"),(0,n.yg)("h3",{id:"user-vs-group-tracking"},"User vs Group tracking"),(0,n.yg)("p",null,"Tracking is based on the ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object defined in the core scheduler. User and group information is retrieved by the shim and communicated via the ",(0,n.yg)("em",{parentName:"p"},"UserGroupInformation")," object as defined in the scheduler interface. A ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object contains:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"user (exactly 1)"),(0,n.yg)("li",{parentName:"ul"},"groups (0 or more)")),(0,n.yg)("p",null,"Limits can be configured for both users and groups at the same time in the same queue. So, in the case of users for which no limit has been configured explicitly but group (to which the user belongs to) limits have configured works based on the group limits configuration. In case of users for which a limit has been configured explicitly works based on its own configured limits irrespective of whether configuration has been set for the corresponding group (to which the user belongs to) or not. In other words, user limit settings always have the higher precedence when group limit settings have been configured too."),(0,n.yg)("p",null,'"*" is also allowed for both users and groups limit configuration. In this case, any user or group needs to go through enforcement checks to ensure limit settings are being honoured properly. However, the tracker does not need to track the wildcard user as a specific user or group is already being tracked during their activities.'),(0,n.yg)("h3",{id:"group-limitations"},"Group limitations"),(0,n.yg)("p",null,"Users can belong to zero, one or multiple groups. In some systems, like unix, a concept of a primary group exists. This concept is not universal and there is no consistent definition of a primary group either. If the system does not define a primary group how would we distinguish between the groups?"),(0,n.yg)("p",null,"In the case the user is a member of multiple groups the assignment of usage to a group also becomes problematic. The decision which group to assign the usage to becomes arbitrary. As an example consider a user with multiple groups assigned. Joe has groups dev and test assigned. When an application is started does that application count towards the limits for the dev group or against the limits for the test group or both?"),(0,n.yg)("p",null,"The ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object contains a slice, list or array, of groups which has a fixed order from the moment of creation. The group resolution configured might not guarantee an ordering which means we cannot rely on the order in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," to be stable. A stable and pre-defined way of choosing a group to track usage against must be defined."),(0,n.yg)("p",null,"The first point to define is that tracking can only occur against zero (0) or one (1) group. Usage can never be tracked against multiple groups. If a user is a member of multiple groups, a group is selected when the first usage is registered for the application. The group selected out of the list of groups in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object to track against is based on the hierarchical queue limit configuration. The hierarchy is considered bottom up, starting from the leaf up to the root. The first group that is specified in the queue hierarchy for limiting usage that matches a group in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object is selected for that application."),(0,n.yg)("p",null,"If no group limits are defined, in the hierarchy, usage is not tracked for a group. If no groups are defined in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object no usage will be tracked against a group."),(0,n.yg)("p",null,"The tracker considers only the group received as part of the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object at the time of first usage registration for the application in the tracker. In case of group changes while the user\u2019s application is actively being tracked, the tracker does not consider the group change. However, If the user submits a new application, the most current group information at that point in time will be used."),(0,n.yg)("p",null,"Until there is full support for groups in the k8shim, group tracking will be limited. No groups are passed by the k8shim to the core. This results in the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object in the current implementation to always have only one group. The group name will be the same as the username. We also have excluded configuration processing for the tracking. For the current tracking implementation as described in the document these limitations will result in the user and group linked to the user to track the same usage."),(0,n.yg)("h3",{id:"cluster-or-queue-based-tracking"},"Cluster or queue based tracking"),(0,n.yg)("p",null,"Tracking user usage will be based on the usage per queue. The full hierarchy of the queue will be tracked. We should not just track the leaf or root of the hierarchy. The overall cluster usage is the same as the usage of the root queue. Cluster level usage does not need separate tracking."),(0,n.yg)("p",null,"The overhead of tracking per queue should be really limited. In most cases a user will run their workloads in a specific queue. Deeply nested queues do also add overhead to the tracking. During testing the impact of workload spread and or deep nesting needs to be assessed. If needed this can be called out in the documentation."),(0,n.yg)("p",null,"We also need to take into account that multiple members of a group could be using different queues in the hierarchy. If tracking usage would be limited to the leaf level, aggregating group usage becomes more difficult and loses transparency."),(0,n.yg)("p",null,"The documentation around limits, part of the enforcement, reference different limits at different levels for users or groups. Tracking at just the leaf or root level could break that functionality. The design should support the current documented features. If during enforcement design a different decision is made then the tracking is not the deciding factor."),(0,n.yg)("h2",{id:"application-tracking"},"Application tracking"),(0,n.yg)("p",null,"Applications go through a number of states within the core scheduler. Allocations linked to applications are the triggers for application state changes. From a tracking perspective we need to define what is considered a running application."),(0,n.yg)("p",null,"Since placeholders and placeholder timeout can play a role in state changes the implementation of the running application tracking must take into account these cases:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"no gang defined"),(0,n.yg)("li",{parentName:"ul"},"gang defined, all or some placeholders replaced"),(0,n.yg)("li",{parentName:"ul"},'gang style "soft" defined, all placeholders time out'),(0,n.yg)("li",{parentName:"ul"},'gang style "hard" defined, all placeholders time out')),(0,n.yg)("h3",{id:"running-state-entry"},"Running state entry"),(0,n.yg)("p",null,"The application when submitted and placed into a queue is in the ",(0,n.yg)("em",{parentName:"p"},"New")," state. At this point there is no allocation or pending request present on the application. After one or more requests, ",(0,n.yg)("em",{parentName:"p"},"AllocationAsks"),", are added the application moves into an ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state. The ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state is exited when the first ",(0,n.yg)("em",{parentName:"p"},"Allocation")," is added to the application. The application then transitions into the Running state."),(0,n.yg)("p",null,"At this point a resource quota would be used by the application and the application should be considered as running from a tracking perspective. This means that the addition of the first ",(0,n.yg)("em",{parentName:"p"},"Allocation")," onto the application also must be the trigger point for the increase of the running applications. This trigger point for tracking is when the application is in the ",(0,n.yg)("em",{parentName:"p"},"Accepted")," state. This is also the point at which the group for the usage tracking needs to be set as described in the ",(0,n.yg)("a",{parentName:"p",href:"#group-limitations"},"group limitations"),"."),(0,n.yg)("p",null,"Note that currently, the application state transition code block in application",(0,n.yg)("em",{parentName:"p"},"state.go updates the application running queue metrics when the application enters _Running")," state. The metric must be updated to be consistent with the above definition of a running application. Linking this back to a state transition the entry into the Running state should be used."),(0,n.yg)("h3",{id:"running-state-exit"},"Running state exit"),(0,n.yg)("p",null,"An application should be considered running as long as at least one allocation is assigned to the application. The removal of the last allocation should decrease the number of running applications. However, we also need to consider the pending requests."),(0,n.yg)("p",null,"As part of the application states the application enters into a ",(0,n.yg)("em",{parentName:"p"},"Completing")," state when the last allocation is removed and there are no pending requests. This automatically progresses into the ",(0,n.yg)("em",{parentName:"p"},"Completed")," state if nothing changes for the application. Applications going into the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state all have no allocations left and pending requests are considered. The entry of the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state thus could be used as a point for triggering the decrease of the running application count."),(0,n.yg)("p",null,"However there are circumstances that the application goes from the ",(0,n.yg)("em",{parentName:"p"},"Completing")," state back into a ",(0,n.yg)("em",{parentName:"p"},"Running")," state. This is linked to auto restart of a pod by Kubernetes. This case must be handled."),(0,n.yg)("p",null,"A last case that needs to be considered is an application that fails. If an application fails it moves into the Failing state. The application does not enter ",(0,n.yg)("em",{parentName:"p"},"Completing"),' but could have incremented the running applications. A failure could be triggered by the gang scheduling style "hard" or the removal of a partition.'),(0,n.yg)("h2",{id:"resource-usage-tracking"},"Resource usage tracking"),(0,n.yg)("p",null,"Resource usage is tracked simply based on the addition or removal of an allocation."),(0,n.yg)("p",null,"Removal of an allocation is an out-of-band action. The shim notifies the core scheduler that an allocation no longer exists and the core updates the tracking based on that removal. If an allocation is preempted the core initiates the removal but still gets notified by the shim that the removal has occurred. Until the confirmation of the shim is received no tracking updates must be created."),(0,n.yg)("p",null,"The replacement of a placeholder by the real allocation for gang scheduling follows a similar concept. However, in that case there is a possibility that there is a discrepancy between the placeholder size and the real allocation. See ",(0,n.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-982"},"YUNIKORN-982")," for more detailed information on this issue. The changes that fixed the accounting for the queues and nodes also need to be taken into account for user based resource tracking."),(0,n.yg)("p",null,"Adding a new allocation to an application triggers the update of the tracked resources for the user and or group as described in the ",(0,n.yg)("a",{parentName:"p",href:"#group-limitations"},"group limitations"),". Enforcement is not a goal of the design document but the enforcement implementation needs to be taken into account. The point to add the resource usage must line up with the point that the queue structure is currently updated and the queue quotas are enforced."),(0,n.yg)("p",null,"The order of the updates: queue structure first then user or user first then queue structure is debatable. The current proposal is to implement the following:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"Update user and group based usage"),(0,n.yg)("li",{parentName:"ul"},"Queue quota enforcement and update"),(0,n.yg)("li",{parentName:"ul"},"If the queue enforcement fails, roll back the user and group based update.")),(0,n.yg)("h2",{id:"scheduler-transparency"},"Scheduler transparency"),(0,n.yg)("p",null,"Resource usage tracking is based on the allocated resource, and linked to the application\u2019s queue path and the application\u2019s ",(0,n.yg)("em",{parentName:"p"},"user")," field. Application tracking is a simple count of the applications, and is linked to the application\u2019s queue path and the application\u2019s user field.\nAs an extension on this we could consider adding the ",(0,n.yg)("em",{parentName:"p"},"applicationID")," into the tracking of the running applications to help with troubleshooting. This is part of the current proposal. The proposal is to not link the running application tracking to the applicationID."),(0,n.yg)("p",null,"The user field of an application is the earlier mentioned ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," object and has all the identifying details needed to track the usage."),(0,n.yg)("p",null,"From the schedulers perspective there should be no special setup needed. The tracking should always work without the need to pre-create a user, group or queue based entry. This means that the tracking cannot fail even if the user or group has no enforcement linked to it and does not exist in the tracker."),(0,n.yg)("p",null,"In summary the tracker must implement:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"User and or group creation on the fly."),(0,n.yg)("li",{parentName:"ul"},"Auto cleanup of tracking information no longer needed."),(0,n.yg)("li",{parentName:"ul"},"Configuration processing needed for enforcement.")),(0,n.yg)("h2",{id:"user-group-manager-ugm"},"User Group Manager (UGM)"),(0,n.yg)("p",null,"Tracking all the resources will be part of a new self-contained module in the scheduler. This means that there must be no imports from the ",(0,n.yg)("inlineCode",{parentName:"p"},"scheduler.objects")," package. This will allow us to run the tracker separately and push updates, if needed, into a background processing queue."),(0,n.yg)("p",null,"There will be one user group manager created per partition as part of the partition creation process. There will be no tracking of user quotas over a partition boundary."),(0,n.yg)("p",null,"The new self-contained module, user group manager contains all specifications and code for tracking and can be extended in the future to include enforcement code."),(0,n.yg)("p",null,"Tracking the resources and application count for all users occurs from startup. This happens irrespective of whether enforcement is configured for the user or group. By starting tracking independently of the enforcement changes in enforcement will always have a consistent view of the resources tracked at least at a user level. Recovery must be tested in combination with the tracking code."),(0,n.yg)("p",null,"Storing data in the user group manager is based on the ",(0,n.yg)("em",{parentName:"p"},"security.UserGroup")," structure content. The built-in ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache")," resolution cannot guarantee that the same object is returned for the same user each time."),(0,n.yg)("h3",{id:"usergroup-cache-impact"},"UserGroup cache impact"),(0,n.yg)("p",null,"The concept of a stable user entry in the cache is not currently present in the ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache"),". This concept will most likely also not be possible based on the fact that group resolution does not guarantee ordering. Based on the assumption that we cannot guarantee group ordering for all group resolutions that are possible the tracking will not rely on it."),(0,n.yg)("p",null,"Currently, ",(0,n.yg)("em",{parentName:"p"},"UserGroupCache")," holds the ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object entry only for the cache period. This is either 300 seconds for a positive resolution or 30 seconds for a negative resolution. After this cache time the entry will be deleted as part of the cache cleanup/expiration process. If the same user submits a second application after the expiry, a new ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," object will be created and stored in the cache. The ",(0,n.yg)("em",{parentName:"p"},"UserGroup"),' object has a property "resolved", which holds a timestamp at which the user group resolution has been executed for the first time. The cache cleaner wakes up after every 60 seconds and deletes all entries whose "resolved" timestamp is older than the cache timeout.'),(0,n.yg)("p",null,"Other internal changes might be needed to make sure all ",(0,n.yg)("em",{parentName:"p"},"UserGroup")," objects are cached correctly and returned as expected internally in the cache. These are left as implementation details for the cache changes."),(0,n.yg)("h3",{id:"tracking-structure"},"Tracking structure"),(0,n.yg)("p",null,"The user group Manager must be able to track usage for users and groups. Users are the primary access point for all tracking. The user group Manager structure will implement the ",(0,n.yg)("a",{parentName:"p",href:"#tracker-interface"},"tracker interface"),"."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype Manager struct {\n users map[string]*userTracker\n groups map[string]*groupTracker\n\n sync.RWMutex\n}\n(m *Manager) checkAppGroup(queuePath, applicationID string, user *security.UserGroup)\n")),(0,n.yg)("p",null,"All objects in the user group manager will be managed internally. Creation of user and or group tracker objects is based on the request to track usage. The objects are added to one of the two structures in the user group manager. Adding user or group objects can only be triggered by an increase of tracked resources. The creation of the user and or group tracker objects is handled by the user group manager. The user group manager is also responsible for setting the usage information for the queue hierarchy directly after creation."),(0,n.yg)("p",null,"The resolution of the group that the usage is tracked against for an application is handled by the user group Manager via the checkAppGroup. As part of an increase of resource usage the Manager will check if the application is already tracked for the user. If the application is already tracked nothing changes. If the application is not tracked the manager will resolve the group to track against and update the userTracker object. If there is no active tracker registered for the group a new groupTracker object will be created and initialised as required."),(0,n.yg)("p",null,"Removal of user or group objects can only be triggered after a decrease of tracked resources has removed the last usage. Usage tracked for a user must be zero. For group tracker objects the application reference count must be zero.\nRemoval of the user and or group tracker objects is done periodically. This cleanup must be ",(0,n.yg)("inlineCode",{parentName:"p"},"go routine")," safe. Updates to either map could be triggered from different routines, scheduler allocation processing or a release of an allocation by a shim."),(0,n.yg)("h3",{id:"tracker-interface"},"Tracker interface"),(0,n.yg)("p",null,"The interface describes the functions that will be exposed by the user group manager. The other scheduler components can rely on the functions defined in the interface to be available to increase, decrease applications and or resource usage and get the tracked resources."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype Tracker interface {\n GetUserResources(user *security.UserGroup) *Resource\n GetGroupResources(group string) *Resource\n\n GetUsersResources() []*userTracker\n GetGroupsResources() []*groupTracker\n\n IncreaseTrackedResource(queuePath, applicationID string, usage *Resource, user *security.UserGroup) error\n DecreaseTrackedResource(queuePath, applicationID string, usage *Resource, removeApp bool, user *security.UserGroup) error\n}\n")),(0,n.yg)("p",null,"The ",(0,n.yg)("em",{parentName:"p"},"IncreaseTrackedResource()")," and ",(0,n.yg)("em",{parentName:"p"},"DecreaseTrackedResource()")," calls will implement the tracking data updates. The Get* calls are providing safe access to the tracked data to be used as part of exposing the data in the REST interface. See ",(0,n.yg)("a",{parentName:"p",href:"#exposure-of-usage-tracking"},"exposure of usage tracking")," for more detail."),(0,n.yg)("p",null,"Applications are added automatically during the call to increase the tracked resources. The first time the applicationID is encountered the structures are updated accordingly and tracking starts. The removal of the application is triggered by leaving the ",(0,n.yg)("a",{parentName:"p",href:"#running-state-exit"},"running state"),", this is equivalent to the removal of the last usage and must also set the removeApp flag to true."),(0,n.yg)("p",null,"Calling ",(0,n.yg)("em",{parentName:"p"},"IncreaseTrackedResource()")," and ",(0,n.yg)("em",{parentName:"p"},"DecreaseTrackedResource()")," with empty or nil parameters is not allowed and will return an error to be handled by the caller. The ",(0,n.yg)("em",{parentName:"p"},"GetUserResource")," and ",(0,n.yg)("em",{parentName:"p"},"GetGroupResource")," calls can return a ",(0,n.yg)("em",{parentName:"p"},"nil")," Resource value. The ",(0,n.yg)("em",{parentName:"p"},"GetUsersResource")," and ",(0,n.yg)("em",{parentName:"p"},"GetGroupsResource")," calls can return an empty slice."),(0,n.yg)("h3",{id:"user-tracking"},"User tracking"),(0,n.yg)("p",null,"The userTracker contains all tracked usage information for a user. Changes for all usage, even the group usage, are part of the change that gets triggered on the user object."),(0,n.yg)("p",null,"The userTracker object contains a reference map to the usage for each application that is tracked linking it to the groupTracker object for the specific application. Multiple applications can be tracked against the same groupTracker object."),(0,n.yg)("p",null,"The group references will be set for each application when usage is added for an application and is not mutable. The existence of a groupTracker for the application can be checked by calling ",(0,n.yg)("em",{parentName:"p"},"hasGroupForApp")," on the userTracker object. It returns true in case the application ID exists in the group mapping, false if it does not. The return value is only based on the existence of the applicationID as the key, not on the value it references."),(0,n.yg)("p",null,"The groupTracker can be set in the userTracker object by calling ",(0,n.yg)("em",{parentName:"p"},"setGroupForApp"),". If the applicationID already exists, the call to set the groupTracker reference is a noop, nothing will change. The reference cannot be changed after it is set. The groupTracker reference can be nil. In the case of a nil reference, no tracking for that application against a group is performed. Even a nil reference cannot be replaced."),(0,n.yg)("p",null,"An increase or decrease of the resources tracked for the user requires the applicationID to be set to a non-empty value. On removal of the last allocation for the application the group reference will be removed from the userTracker object. To remove a running application from the userTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true. Removal of the groupTracker reference can only occur as part of a ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call."),(0,n.yg)("p",null,"If there are no applications left in the group references the object will be removed by the cleanup run from the user group manager. This will also mean that there is no usage tracked anymore by the referenced queueTracker object."),(0,n.yg)("p",null,"The usage per queue is stored in a queue structure specific for this user. The queueTracker object provides a hierarchical structure. This structure starts at the root of the queue hierarchy and only contains child queues for which a usage is being tracked. The hierarchy must be updated, add or delete of child entries, as part of the updates that are processed."),(0,n.yg)("p",null,"The creation of the root queueTracker is part of the creating a new userTracker object."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype userTracker struct {\n userName string\n group map[string]*groupTracker\n queue *queueTracker\n \n sync.RWMutex\n}\n\nnewUserTracker(queuePath string, user *security.UserGroup) *userTracker\n\n(ut *userTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(ut *userTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n(ut *userTracker) hasGroupForApp(applicationID string) bool\n(ut *userTracker) setGroupForApp(applicationID string, groupTrack *groupTracker)\n")),(0,n.yg)("h3",{id:"group-tracking"},"Group tracking"),(0,n.yg)("p",null,"The groupTracker contains all tracked usage information for a group. This object can be shared by multiple users for one or more applications. It adds the applications that are tracked for this specific group automatically to the list. For this it expects an applicationID to be set to a non-empty value for each ",(0,n.yg)("em",{parentName:"p"},"increaseResource")," call."),(0,n.yg)("p",null,"To simply decrease the resources tracked for the group the applicationID could be empty. On removal of the last allocation for the application the application will be removed from the groupTracker object. To remove a running application from the groupTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true."),(0,n.yg)("p",null,"If there are no entries left in the applications tracked in the groupTracker the object will be removed by the cleanup run from the user group manager. This will also mean that there is no usage tracked any more by the referenced queueTracker object."),(0,n.yg)("p",null,"The usage per queue is stored in a queue structure specific for this group. The queueTracker object provides a hierarchical structure. This structure starts at the root of the queue hierarchy and only contains child queues for which a usage is being tracked. The hierarchy must be updated, add or delete of child entries, as part of the updates that are processed."),(0,n.yg)("p",null,"The creation of the root queueTracker is part of the creating a new groupTracker object."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype groupTracker struct {\n groupName string\n applications map[string]bool\n queue *queueTracker\n \n sync.RWMutex\n}\n\nnewGroupTracker(queuePath string, group string) *groupTracker\n\n(gt *groupTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(gt *groupTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n")),(0,n.yg)("h3",{id:"queue-tracking"},"Queue tracking"),(0,n.yg)("p",null,"The queueTracker acts as a base for both user and group tracking. It provides the actual location for the tracked usage.The top of the structure, which is referenced from the userTracker or groupTracker objects, contains the root queue usage. The queueTracker is only referenced by one userTracker or one groupTracker object and must not be shared. This means that we should not require any locking within the queueTracker object."),(0,n.yg)("p",null,"The queue hierarchy below the root, for which a usage is registered, is part of the childQueues. Each part of the full queue path creates a new level of objects. This structure shows a sparse hierarchical queue structure. It may not represent the full queue structure as known in the scheduler."),(0,n.yg)("p",null,'The creation of the root queueTracker returns a plain object without usage set and a fixed queueName of "root". The usage should then be updated by a call to ',(0,n.yg)("em",{parentName:"p"},"increaseResource"),". The call must handle the recursive creation of the queue path as given. It expects an applicationID to be set to a non-empty value for each call."),(0,n.yg)("p",null,"To simply decrease the resources tracked for the queue the applicationID can be empty. On removal of the last allocation for the application the application will be removed from the queueTracker. To remove a running application from the queueTracker the applicationID must be set in the ",(0,n.yg)("em",{parentName:"p"},"decreaseResource")," call and the flag removeApp must be set to true."),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre"},"package user_group_manager\n\ntype queueTracker struct {\n queueName string\n resourceUsage *Resource\n runningApplications map[string]boolean\n\n childQueues map[string]*queueTracker\n}\n\nnewQueueTracker() *queueTracker\n\n(qt *queueTracker) increaseResource(queuePath, applicationID string, usage *Resource)\n(qt *queueTracker) decreaseResource(queuePath, applicationID string, usage *Resource, removeApp bool)\n")),(0,n.yg)("h3",{id:"update-consistency"},"Update consistency"),(0,n.yg)("p",null,"All changes are triggered against a userTracker object. Since enforcement of a quota is out of scope of this design we can ignore update failures due to quota exhaustion. There is no requirement or possibility that updates need to be rolled back."),(0,n.yg)("p",null,"Usage updates can be triggered from two points: allocation by the scheduler and releases by a shim. Allocations as well as releases need to update both user and group usage information. We must guarantee that for both the full hierarchy is changed or neither are changed."),(0,n.yg)("p",null,"The releases are also processed asynchronously from the scheduling cycle. This means that we have to be able to guarantee that the increases and decreases are applied consistently to both objects also. Locking of the objects to serialise changes must be in place to support this."),(0,n.yg)("p",null,"The other point is the update ordering and locking. The increase and decrease processing must follow the same order. Both must update the userTracker and related groupTracker objects in the same order. This is a requirement to prevent the processing of being able to deadlock while updating the same user for a simultaneous increase and decrease."),(0,n.yg)("p",null,"For groupTracker updates that originate from two different users the locking of the groupTracker object is required. One of the two updates will be able to proceed while the other waits for the update to finalise."),(0,n.yg)("p",null,"A final consideration is the consistency of two updates on the same object that follow each other closely. If the first update removes all existing usage the userTracker or groupTracker object is cleared for removal. While the update is in progress a second update comes in to add a new usage to the same object. The resolution of the userTracker in the user group manager has finished. The code has a reference to the object. Processing is waiting to lock the userTracker object. This point could cause the object to become unlinked and usage tracking information to be lost. The implementation needs to prevent this race condition."),(0,n.yg)("h3",{id:"exposure-of-usage-tracking"},"Exposure of usage tracking"),(0,n.yg)("p",null,"The usage tracking information that is part of the user group manager must be exposed for external consumption. All our current information is exposed via a REST call."),(0,n.yg)("p",null,"Based on the current REST api definition for other object the proposal is to expose the following new endpoints:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"/ws/v1/partition/{partitionName}/usage/users"),(0,n.yg)("li",{parentName:"ul"},"/ws/v1/partition/{partitionName}/usage/groups")),(0,n.yg)("p",null,"For both endpoints we expose the full queue hierarchy. As an example below the approximate output for the user's endpoint for one user:"),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "userName": "user1",\n "groups": {\n "app2": "tester"\n },\n "queues":\n {\n "queuename": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuename": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuename": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,n.yg)("p",null,"An example below the approximate output for the groups endpoint for one group:"),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "groupName" : "tester",\n "applications": ["app2"],\n "queues":\n {\n "queuename": "root",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app2"],\n "children": [\n {\n "queuename": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app2"],\n "children": []\n }\n ]\n }\n }\n]\n')))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/203393bb.1ed7e549.js b/assets/js/203393bb.1ed7e549.js deleted file mode 100644 index fa0c451d6cb..00000000000 --- a/assets/js/203393bb.1ed7e549.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[10783],{58860:(e,t,a)=>{a.d(t,{xA:()=>d,yg:()=>g});var n=a(37953);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(a),u=i,g=p["".concat(l,".").concat(u)]||p[u]||h[u]||o;return a?n.createElement(g,r(r({ref:t},d),{},{components:a})):n.createElement(g,r({ref:t},d))}));function g(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:i,r[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=a(72994),i=(a(37953),a(58860));const o={id:"scheduler_object_states",title:"Scheduler Object States"},r=void 0,s={unversionedId:"developer_guide/scheduler_object_states",id:"developer_guide/scheduler_object_states",title:"Scheduler Object States",description:"\x3c!--",source:"@site/docs/developer_guide/scheduler_object_states.md",sourceDirName:"developer_guide",slug:"/developer_guide/scheduler_object_states",permalink:"/docs/next/developer_guide/scheduler_object_states",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler_object_states",title:"Scheduler Object States"},sidebar:"docs",previous:{title:"Development in CodeReady Containers",permalink:"/docs/next/developer_guide/openshift_development"},next:{title:"Architecture",permalink:"/docs/next/design/architecture"}},l={},c=[{value:"Core Scheduler",id:"core-scheduler",level:2},{value:"Application State",id:"application-state",level:3},{value:"Object State",id:"object-state",level:3},{value:"Node",id:"node",level:3},{value:"K8Shim Resource Manager",id:"k8shim-resource-manager",level:2},{value:"Application",id:"application",level:3},{value:"Task",id:"task",level:3},{value:"Node",id:"node-1",level:3}],d={toc:c},p="wrapper";function h(e){let{components:t,...o}=e;return(0,i.yg)(p,(0,n.A)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("p",null,"The YuniKorn project uses state machines to track the states of different objects.\nThis ranges from applications in the core to nodes in the k8shim.\nThe state machines are independent and not shared between the resource managers and core.\nA resource manager shim, and the core can thus have an independent idea of the state of a similar object."),(0,i.yg)("h2",{id:"core-scheduler"},"Core Scheduler"),(0,i.yg)("p",null,"State change are triggered by events that get processed.\nOne event can cause a change for multiple states or no change at all."),(0,i.yg)("h3",{id:"application-state"},"Application State"),(0,i.yg)("p",null,"Applications have a complex state model.\nAn application when created starts ain the new state."),(0,i.yg)("p",null,"An application can have the following states:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"New: A new application that is being submitted or created, from here the application transitions into the accepted state when it is ready for scheduling.\nThe first ask to be added will trigger the transition."),(0,i.yg)("li",{parentName:"ul"},"Accepted: The application is ready and part of the scheduling cycle.\nOn allocation of the first ask the application moves into a starting state.\nThis state is part of the normal scheduling cycle."),(0,i.yg)("li",{parentName:"ul"},"Starting: The application has exactly one allocation confirmed this corresponds to one running container/pod.\nThe application transitions to running if and when more allocations are added to the application.\nThis state times out automatically to prevent applications that consist of just one allocation from getting stuck in this state.\nThe current time out is set to 5 minutes, and cannot be changed.\nIf after the timeout expires the application will auto transition to running.\nThe state change on time out is independent of the number of allocations added.\nThis state is part of the normal scheduling cycle."),(0,i.yg)("li",{parentName:"ul"},"Running: The state in which the application will spend most of its time.\nContainers/pods can be added to and removed from the application.\nThis state is part of the normal scheduling cycle."),(0,i.yg)("li",{parentName:"ul"},"Completing: An application that has no pending requests or running containers/pod will be completing.\nThis state shows that the application has not been marked completed yet but currently is not actively being scheduled."),(0,i.yg)("li",{parentName:"ul"},"Completed: An application is considered completed when it has been in the completing state for a defined time period.\nFrom this state the application can only move to the Expired state, and it cannot move back into any of scheduling states (Running or Completing)\nThe current timeout is set to 30 seconds."),(0,i.yg)("li",{parentName:"ul"},"Expired: The completed application is tracked for a period of time, after that is expired and deleted from the scheduler.\nThis is a final state and after this state the application cannot be tracked anymore. "),(0,i.yg)("li",{parentName:"ul"},"Failing: An application marked for failing, what still has some allocations or asks what needs to be cleaned up before entering into the Failed state.\nThe application can be Failing when the partition it belongs to is removed or during gang scheduling, if the placeholder processing times out, and the application has no real allocations yet."),(0,i.yg)("li",{parentName:"ul"},"Failed: An application is considered failed when it was marked for failure and all the pending requests and allocations were already removed.\nFrom this state the application can only move to the Expired state."),(0,i.yg)("li",{parentName:"ul"},"Rejected: The application was rejected when it was added to the scheduler.\nThis only happens when a resource manager tries to add a new application, when it gets created in a New state, and the scheduler rejects the creation.\nApplications can be rejected due ACLs denying access to a queue the application has specified, or a placement via placement rules has failed. From this state the application can only move to the Expired state.")),(0,i.yg)("p",null,"The events that can trigger a state change:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Reject: rejecting the application by the scheduler (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Run: progress an application to the next active state (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Complete: mark an application as idle or complete (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Fail: fail an application (source: resource manager or core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Expire: progress the application to the expired state and remove it from the scheduler (source: core scheduler)")),(0,i.yg)("p",null,"Here is a diagram that shows the states with the event that causes the state to change:",(0,i.yg)("br",{parentName:"p"}),"\n",(0,i.yg)("img",{alt:"application state diagram",src:a(56991).A,width:"900",height:"927"})),(0,i.yg)("h3",{id:"object-state"},"Object State"),(0,i.yg)("p",null,"The object state is used by the following objects:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"queues"),(0,i.yg)("li",{parentName:"ul"},"partitions")),(0,i.yg)("p",null,"The object states are as follows: "),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Active: The object is active and used during the scheduling cycle.\nThis is the starting and normal state of an object.\nAn active object transitions to draining when it is removed. "),(0,i.yg)("li",{parentName:"ul"},"Stopped: The object is stopped and no longer actively scheduled.\nThe object if empty is ready to be removed from the scheduler.\nThe object can transition back into active state if it gets re-started."),(0,i.yg)("li",{parentName:"ul"},"Draining: Before an object can be removed it needs to be cleaned up.\nThe cleanup starts with placing the object in the draining state.\nIn this state it does not accept additions or changes but is still actively being scheduled.\nThis allows for a graceful shutdown, cleanup and removal of the object.\nThis is the final state.")),(0,i.yg)("p",null,"The events that can trigger a state change:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Start: make the object active (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Stop: make the object inactive (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Remove: mark an object for removal (source: core scheduler)")),(0,i.yg)("p",null,"Here is a diagram that shows the states with the event that causes the state to change:",(0,i.yg)("br",{parentName:"p"}),"\n",(0,i.yg)("img",{alt:"object state diagram",src:a(95076).A,width:"620",height:"266"})),(0,i.yg)("h3",{id:"node"},"Node"),(0,i.yg)("p",null,"Node objects in the core are not using a state machine but do have a state.\nA node can have one of two states: ",(0,i.yg)("inlineCode",{parentName:"p"},"schedulable")," or ",(0,i.yg)("inlineCode",{parentName:"p"},"not schedulable"),".\nThere is no complex state model or complex transition logic.\nThe scheduler can either use the node or not."),(0,i.yg)("p",null,"The node status changes based on the status provided by the resource manager (shim) that owns the node. "),(0,i.yg)("h2",{id:"k8shim-resource-manager"},"K8Shim Resource Manager"),(0,i.yg)("h3",{id:"application"},"Application"),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"application state diagram",src:a(38162).A,width:"814",height:"899"})),(0,i.yg)("h3",{id:"task"},"Task"),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"task state diagram",src:a(26997).A,width:"891",height:"871"})),(0,i.yg)("h3",{id:"node-1"},"Node"),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"node state diagram",src:a(5794).A,width:"546",height:"523"})))}h.isMDXComponent=!0},56991:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/application-state-0cb61236b8d98b254dbcd00fbaff3ddd.png"},38162:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/k8shim-application-state-1b8df985a622da0f105edde142b73243.png"},5794:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/k8shim-node-state-cb64692729955fb1eb0899e747845921.png"},26997:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/k8shim-task-state-14b1032c3d70d0244a074fd1ca2cb4fc.png"},95076:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/object-state-ce78c19f65c895bbbddd0e48b4c22d8f.png"}}]); \ No newline at end of file diff --git a/assets/js/203393bb.b8df8246.js b/assets/js/203393bb.b8df8246.js new file mode 100644 index 00000000000..f8f3a9a596c --- /dev/null +++ b/assets/js/203393bb.b8df8246.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[10783],{58860:(e,t,a)=>{a.d(t,{xA:()=>d,yg:()=>g});var n=a(37953);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(a),u=i,g=p["".concat(l,".").concat(u)]||p[u]||h[u]||r;return a?n.createElement(g,o(o({ref:t},d),{},{components:a})):n.createElement(g,o({ref:t},d))}));function g(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:i,o[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var n=a(72994),i=(a(37953),a(58860));const r={id:"scheduler_object_states",title:"Scheduler Object States"},o=void 0,s={unversionedId:"developer_guide/scheduler_object_states",id:"developer_guide/scheduler_object_states",title:"Scheduler Object States",description:"\x3c!--",source:"@site/docs/developer_guide/scheduler_object_states.md",sourceDirName:"developer_guide",slug:"/developer_guide/scheduler_object_states",permalink:"/docs/next/developer_guide/scheduler_object_states",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler_object_states",title:"Scheduler Object States"},sidebar:"docs",previous:{title:"Development in CodeReady Containers",permalink:"/docs/next/developer_guide/openshift_development"},next:{title:"Architecture",permalink:"/docs/next/design/architecture"}},l={},c=[{value:"Core Scheduler",id:"core-scheduler",level:2},{value:"Application State",id:"application-state",level:3},{value:"Object State",id:"object-state",level:3},{value:"Node",id:"node",level:3},{value:"K8Shim Resource Manager",id:"k8shim-resource-manager",level:2},{value:"Application",id:"application",level:3},{value:"Task",id:"task",level:3}],d={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,i.yg)(p,(0,n.A)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("p",null,"The YuniKorn project uses state machines to track the states of different objects.\nThis ranges from applications in the core to nodes in the k8shim.\nThe state machines are independent and not shared between the resource managers and core.\nA resource manager shim, and the core can thus have an independent idea of the state of a similar object."),(0,i.yg)("h2",{id:"core-scheduler"},"Core Scheduler"),(0,i.yg)("p",null,"State change are triggered by events that get processed.\nOne event can cause a change for multiple states or no change at all."),(0,i.yg)("h3",{id:"application-state"},"Application State"),(0,i.yg)("p",null,"Applications have a complex state model.\nAn application when created starts ain the new state."),(0,i.yg)("p",null,"An application can have the following states:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"New: A new application that is being submitted or created, from here the application transitions into the accepted state when it is ready for scheduling.\nThe first ask to be added will trigger the transition."),(0,i.yg)("li",{parentName:"ul"},"Accepted: The application is ready and part of the scheduling cycle.\nOn allocation of the first ask the application moves into a running state.\nThis state is part of the normal scheduling cycle."),(0,i.yg)("li",{parentName:"ul"},"Running: The state in which the application will spend most of its time.\nContainers/pods can be added to and removed from the application.\nThis state is part of the normal scheduling cycle."),(0,i.yg)("li",{parentName:"ul"},"Completing: An application that has no pending requests or running containers/pod will be completing.\nThis state shows that the application has not been marked completed yet but currently is not actively being scheduled."),(0,i.yg)("li",{parentName:"ul"},"Completed: An application is considered completed when it has been in the completing state for a defined time period.\nFrom this state the application can only move to the Expired state, and it cannot move back into any of scheduling states (Running or Completing)\nThe current timeout is set to 30 seconds."),(0,i.yg)("li",{parentName:"ul"},"Expired: The completed application is tracked for a period of time, after that is expired and deleted from the scheduler.\nThis is a final state and after this state the application cannot be tracked anymore. "),(0,i.yg)("li",{parentName:"ul"},"Failing: An application marked for failing, what still has some allocations or asks what needs to be cleaned up before entering into the Failed state.\nThe application can be Failing when the partition it belongs to is removed or during gang scheduling, if the placeholder processing times out, and the application has no real allocations yet."),(0,i.yg)("li",{parentName:"ul"},"Failed: An application is considered failed when it was marked for failure and all the pending requests and allocations were already removed.\nFrom this state the application can only move to the Expired state."),(0,i.yg)("li",{parentName:"ul"},"Rejected: The application was rejected when it was added to the scheduler.\nThis only happens when a resource manager tries to add a new application, when it gets created in a New state, and the scheduler rejects the creation.\nApplications can be rejected due ACLs denying access to a queue the application has specified, or a placement via placement rules has failed. From this state the application can only move to the Expired state.")),(0,i.yg)("p",null,"The events that can trigger a state change:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Reject: rejecting the application by the scheduler (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Run: progress an application to the next active state (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Complete: mark an application as idle or complete (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Fail: fail an application (source: resource manager or core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Expire: progress the application to the expired state and remove it from the scheduler (source: core scheduler)")),(0,i.yg)("p",null,"Here is a diagram that shows the states with the event that causes the state to change:",(0,i.yg)("br",{parentName:"p"}),"\n",(0,i.yg)("img",{alt:"application state diagram",src:a(56991).A,width:"673",height:"819"})),(0,i.yg)("h3",{id:"object-state"},"Object State"),(0,i.yg)("p",null,"The object state is used by the following objects:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"queues"),(0,i.yg)("li",{parentName:"ul"},"partitions")),(0,i.yg)("p",null,"The object states are as follows: "),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Active: The object is active and used during the scheduling cycle.\nThis is the starting and normal state of an object.\nAn active object transitions to draining when it is removed. "),(0,i.yg)("li",{parentName:"ul"},"Stopped: The object is stopped and no longer actively scheduled.\nThe object if empty is ready to be removed from the scheduler.\nThe object can transition back into active state if it gets re-started."),(0,i.yg)("li",{parentName:"ul"},"Draining: Before an object can be removed it needs to be cleaned up.\nThe cleanup starts with placing the object in the draining state.\nIn this state it does not accept additions or changes but is still actively being scheduled.\nThis allows for a graceful shutdown, cleanup and removal of the object.\nThis is the final state.")),(0,i.yg)("p",null,"The events that can trigger a state change:"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"Start: make the object active (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Stop: make the object inactive (source: core scheduler)"),(0,i.yg)("li",{parentName:"ul"},"Remove: mark an object for removal (source: core scheduler)")),(0,i.yg)("p",null,"Here is a diagram that shows the states with the event that causes the state to change:",(0,i.yg)("br",{parentName:"p"}),"\n",(0,i.yg)("img",{alt:"object state diagram",src:a(95076).A,width:"620",height:"266"})),(0,i.yg)("h3",{id:"node"},"Node"),(0,i.yg)("p",null,"Node objects in the core are not using a state machine but do have a state.\nA node can have one of two states: ",(0,i.yg)("inlineCode",{parentName:"p"},"schedulable")," or ",(0,i.yg)("inlineCode",{parentName:"p"},"not schedulable"),".\nThere is no complex state model or complex transition logic.\nThe scheduler can either use the node or not."),(0,i.yg)("p",null,"The node status changes based on the status provided by the resource manager (shim) that owns the node. "),(0,i.yg)("h2",{id:"k8shim-resource-manager"},"K8Shim Resource Manager"),(0,i.yg)("h3",{id:"application"},"Application"),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"application state diagram",src:a(38162).A,width:"814",height:"899"})),(0,i.yg)("h3",{id:"task"},"Task"),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"task state diagram",src:a(26997).A,width:"891",height:"871"})))}h.isMDXComponent=!0},56991:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/application-state-43c26f8a6a803d863e8ef73311f786eb.png"},38162:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/k8shim-application-state-1b8df985a622da0f105edde142b73243.png"},26997:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/k8shim-task-state-14b1032c3d70d0244a074fd1ca2cb4fc.png"},95076:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/object-state-ce78c19f65c895bbbddd0e48b4c22d8f.png"}}]); \ No newline at end of file diff --git a/assets/js/3259ac92.97730d2c.js b/assets/js/3259ac92.97730d2c.js deleted file mode 100644 index 204b1bc67ad..00000000000 --- a/assets/js/3259ac92.97730d2c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[82495],{58860:(e,n,i)=>{i.d(n,{xA:()=>g,yg:()=>d});var a=i(37953);function l(e,n,i){return n in e?Object.defineProperty(e,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[n]=i,e}function r(e,n){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),i.push.apply(i,a)}return i}function t(e){for(var n=1;n=0||(l[i]=e[i]);return l}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(l[i]=e[i])}return l}var s=a.createContext({}),p=function(e){var n=a.useContext(s),i=n;return e&&(i="function"==typeof e?e(n):t(t({},n),e)),i},g=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},y=a.forwardRef((function(e,n){var i=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,g=o(e,["components","mdxType","originalType","parentName"]),u=p(i),y=l,d=u["".concat(s,".").concat(y)]||u[y]||m[y]||r;return i?a.createElement(d,t(t({ref:n},g),{},{components:i})):a.createElement(d,t({ref:n},g))}));function d(e,n){var i=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var r=i.length,t=new Array(r);t[0]=y;var o={};for(var s in n)hasOwnProperty.call(n,s)&&(o[s]=n[s]);o.originalType=e,o[u]="string"==typeof e?e:l,t[1]=o;for(var p=2;p{i.r(n),i.d(n,{assets:()=>s,contentTitle:()=>t,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var a=i(72994),l=(i(37953),i(58860));const r={id:"config_v2",title:"Configuration V2"},t=void 0,o={unversionedId:"design/config_v2",id:"design/config_v2",title:"Configuration V2",description:"\x3c!--",source:"@site/docs/design/config_v2.md",sourceDirName:"design",slug:"/design/config_v2",permalink:"/docs/next/design/config_v2",draft:!1,tags:[],version:"current",frontMatter:{id:"config_v2",title:"Configuration V2"},sidebar:"docs",previous:{title:"Batch Workloads Ordering with StateAware Policy",permalink:"/docs/next/design/state_aware_scheduling"},next:{title:"Scheduler Configuration",permalink:"/docs/next/design/scheduler_configuration"}},s={},p=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:3},{value:"Non-Goals",id:"non-goals",level:3},{value:"References",id:"references",level:3},{value:"Implementation JIRA",id:"implementation-jira",level:4},{value:"Other relevant JIRAs",id:"other-relevant-jiras",level:4},{value:"Services to cover",id:"services-to-cover",level:3},{value:"Services excluded",id:"services-excluded",level:3},{value:"Configuration format",id:"configuration-format",level:2},{value:"Mutability of configuration values",id:"mutability-of-configuration-values",level:3},{value:"Update handling",id:"update-handling",level:3},{value:"Legacy configuration handling",id:"legacy-configuration-handling",level:3},{value:"Environment variables",id:"environment-variables",level:3},{value:"Helm considerations",id:"helm-considerations",level:3},{value:"Core Configuration",id:"core-configuration",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Default ConfigMap",id:"default-configmap",level:3},{value:"Admission Controller Configuration",id:"admission-controller-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables",level:4},{value:"Removed CLI Options",id:"removed-cli-options",level:4},{value:"Scheduler (Standard) Configuration",id:"scheduler-standard-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables-1",level:4},{value:"Removed CLI Options",id:"removed-cli-options-1",level:4},{value:"Scheduler (Plugin) Configuration",id:"scheduler-plugin-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables-2",level:4},{value:"Removed CLI Options",id:"removed-cli-options-2",level:4},{value:"Helm Configuration",id:"helm-configuration",level:3},{value:"Removed Options",id:"removed-options",level:4},{value:"Deprecated Options",id:"deprecated-options",level:4}],g={toc:p},u="wrapper";function m(e){let{components:n,...i}=e;return(0,l.yg)(u,(0,a.A)({},g,i,{components:n,mdxType:"MDXLayout"}),(0,l.yg)("h2",{id:"introduction"},"Introduction"),(0,l.yg)("p",null,"Over time the YuniKorn configuration has increased in complexity. The current\nconfiguration for YuniKorn is split over a number of different options, file\nand command line, and formats. There is a requirement now to define an overall\nconfiguration approach that can be used for all components."),(0,l.yg)("h3",{id:"goals"},"Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Define a configuration format"),(0,l.yg)("li",{parentName:"ul"},"Define an update and modification strategy"),(0,l.yg)("li",{parentName:"ul"},"Provide consistency between configuration of YuniKorn components"),(0,l.yg)("li",{parentName:"ul"},"Legacy migration strategy")),(0,l.yg)("h3",{id:"non-goals"},"Non-Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Redefine the queue configuration"),(0,l.yg)("li",{parentName:"ul"},"Migration timeline for the old configuration options")),(0,l.yg)("h3",{id:"references"},"References"),(0,l.yg)("h4",{id:"implementation-jira"},"Implementation JIRA"),(0,l.yg)("p",null,(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-1221"},"YUNIKORN-1221")," - ","[Umbrella]"," Configuration V2"),(0,l.yg)("h4",{id:"other-relevant-jiras"},"Other relevant JIRAs"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-455"},"YUNIKORN-455")," - Make the core configurable"),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1213"},"YUNIKORN-1213")," - Background health checker needs to be configurable"),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1335"},"YUNIKORN-1335")," - Write yunikorn-web error logs to stderr")),(0,l.yg)("h3",{id:"services-to-cover"},"Services to cover"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Scheduler (Standard) - K8Shim + Core"),(0,l.yg)("li",{parentName:"ul"},"Scheduler (Plugin) - K8Shim + Core"),(0,l.yg)("li",{parentName:"ul"},"Admission controller")),(0,l.yg)("h3",{id:"services-excluded"},"Services excluded"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Web UI (not needed after ",(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1335"},"YUNIKORN-1335"),")")),(0,l.yg)("h2",{id:"configuration-format"},"Configuration format"),(0,l.yg)("p",null,"Currently only Kubernetes is a supported deployment pattern. Future shims may\nneed an alternative configuration syntax. To enable this, we will update the\nscheduler interface to support passing the core configuration (the content of\nthe ",(0,l.yg)("inlineCode",{parentName:"p"},"queues.yaml")," ConfigMap entry) to the core on startup and refresh. The\nexisting config watcher functionality in the core will be removed and the shim\nwill gain the responsibility for watching for ConfigMap changes. The shim\nactually already has this ability now, it is just not used."),(0,l.yg)("p",null,"We will use two ConfigMaps to configure YuniKorn:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"yunikorn-defaults"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"This will be a new ConfigMap written by Helm; it will contain only values\nexplicitly configured by an administrator via Helm variables."))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"yunikorn-configs"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"This ConfigMap will contain overrides for yunikorn-defaults. It was\npreviously a Helm hook in previous YuniKorn releases; it will no longer\nbe managed by Helm and may be updated freely by third-party tools.")))),(0,l.yg)("p",null,"The effective configuration will be the combination of both ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-defaults"),"\nand ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-configs"),", with ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-configs")," taking precedence."),(0,l.yg)("p",null,"Neither ConfigMap (even the existing one) is required for proper functionality.\nIn the case where a ConfigMap does not exist, we will use compiled-in defaults\nfor all options. This enables bootstrapping in a variety of environments,\nincluding local development mode, as the ConfigMap need not exist to bring the\nscheduler components up. Future configuration options should be set via the\nConfigMap exclusively."),(0,l.yg)("h3",{id:"mutability-of-configuration-values"},"Mutability of configuration values"),(0,l.yg)("p",null,"We should strive for hot-reload of all configuration values where possible.\nWhere hot-reload is not implemented, this should be clearly documented. For the\ninitial release, the core config and admission controller will be\nhot-reloadable but many items in the shim will likely not be. The shim was not\ndesigned to hot-reload anything so this will be a large future task. Some items\nmay never be reloadable due to architectural limitations."),(0,l.yg)("h3",{id:"update-handling"},"Update handling"),(0,l.yg)("p",null,"Given the security issues involved with updates, the default Kubernetes access\ncontrol alone should be used for ConfigMap updates. We can still syntax-check\nthe core side of the configuration in the admission controller as before.\nPartial updates are allowed as Kubernetes supports patching of ConfigMaps."),(0,l.yg)("h3",{id:"legacy-configuration-handling"},"Legacy configuration handling"),(0,l.yg)("p",null,"Helm will be updated to render all existing legacy options into the\n",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-defaults")," ConfigMap for easier transition to the new configuration\nformat. Consequently, it is not necessary for YuniKorn components to parse the\nold environment and command-line arguments."),(0,l.yg)("h3",{id:"environment-variables"},"Environment variables"),(0,l.yg)("p",null,"All environment variables for all services will be removed, with the exception\nof:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"NAMESPACE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Default value: ",(0,l.yg)("inlineCode",{parentName:"li"},"default")),(0,l.yg)("li",{parentName:"ul"},"Will be auto-populated from Helm and resolve to the pod's running\nnamespace"),(0,l.yg)("li",{parentName:"ul"},"Needed so that YuniKorn can determine what namespace it was launched in"),(0,l.yg)("li",{parentName:"ul"},"Should only be provided explicitly at development time"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"KUBECONFIG"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Default value: ",(0,l.yg)("inlineCode",{parentName:"li"},"$HOME/.kube/config")),(0,l.yg)("li",{parentName:"ul"},"Will be ignored if running inside Kubernetes; in-cluster configuration\nwill be used in that case"),(0,l.yg)("li",{parentName:"ul"},"Needed so that we can bootstrap to K8s and load the YuniKorn ConfigMap at\nruntime"),(0,l.yg)("li",{parentName:"ul"},"Should only be provided explicitly at development time")))),(0,l.yg)("h3",{id:"helm-considerations"},"Helm considerations"),(0,l.yg)("p",null,"All configuration options which have moved into the ConfigMap will be marked as\ndeprecated in the Helm chart documentation. Their replacement is the more\ngeneric ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikornDefaults")," dictionary. If the legacy values are present but\nthe associated ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikornDefaults")," entry is missing, the legacy configuration\nvalue will be used. This will allow users some time to migrate to the new\nconfiguration style. The legacy attributes will be removed in a future release."),(0,l.yg)("h3",{id:"core-configuration"},"Core Configuration"),(0,l.yg)("p",null,"The core scheduler configuration is loaded from the ",(0,l.yg)("inlineCode",{parentName:"p"},"queues.yaml")," section of\nthe ConfigMap, assuming ",(0,l.yg)("inlineCode",{parentName:"p"},"service.policyGroup")," is set to the default value\n",(0,l.yg)("inlineCode",{parentName:"p"},"queues"),". If the policy group has been customized, core scheduler configuration\nwill be read from ",(0,l.yg)("inlineCode",{parentName:"p"},"{service.policyGroup}.yaml"),". This section is special as its\ncontents are passed directly to the core for evaluation and update and is not\nread directly by the shim. The content of this section is unchanged from prior\nreleases."),(0,l.yg)("h2",{id:"appendix"},"Appendix"),(0,l.yg)("h3",{id:"default-configmap"},"Default ConfigMap"),(0,l.yg)("p",null,"If not present, the default ConfigMap will resolve to these defaults.\nAdditionally, individual options will resolve to those listed here if not\nspecified. Note that these values are subject to change in future releases."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: yunikorn-configs\ndata:\n service.clusterId: "mycluster"\n service.policyGroup: "queues"\n service.schedulingInterval: "1s"\n service.volumeBindTimeout: "10s"\n service.eventChannelCapacity: "1048576"\n service.dispatchTimeout: "5m"\n service.operatorPlugins: "general"\n service.disableGangScheduling: "false"\n service.enableConfigHotRefresh: "true"\n service.placeholderImage: "registry.k8s.io/pause:3.7"\n service.instanceTypeNodeLabelKey: "node.kubernetes.io/instance-type"\n health.checkInterval: "30s"\n log.level: "0"\n kubernetes.qps: "1000"\n kubernetes.burst: "1000"\n admissionController.webHook.amServiceName: "yunikorn-admission-controller-service"\n admissionController.webHook.schedulerServiceAddress: "yunikorn-service:9080"\n admissionController.filtering.processNamespaces: ""\n admissionController.filtering.bypassNamespaces: "^kube-system$"\n admissionController.filtering.labelNamespaces: ""\n admissionController.filtering.noLabelNamespaces: ""\n admissionController.accessControl.bypassAuth: "false"\n admissionController.accessControl.trustControllers: "true"\n admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system:"\n admissionController.accessControl.externalUsers: ""\n admissionController.accessControl.externalGroups: ""\n queues.yaml: |\n partitions:\n - name: default\n placementrules:\n - name: tag\n value: namespace\n create: true\n queues:\n - name: root\n submitacl: \'*\'`\n')),(0,l.yg)("h3",{id:"admission-controller-configuration"},"Admission Controller Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"POLICY_GROUP"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ENABLE_CONFIG_HOT_REFRESH"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"SCHEDULER_SERVICE_ADDRESS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.webHook.schedulerServiceAddress")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_SERVICE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.webHook.amServiceName")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_NAMESPACE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use Environment variable: ",(0,l.yg)("inlineCode",{parentName:"li"},"NAMESPACE")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_PROCESS_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.processNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_BYPASS_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.bypassNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSON_CONTROLLER_LABEL_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.labelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_NO_LABEL_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.noLabelNamespaces"))))),(0,l.yg)("h4",{id:"removed-cli-options"},"Removed CLI Options"),(0,l.yg)("p",null,"None"),(0,l.yg)("h3",{id:"scheduler-standard-configuration"},"Scheduler (Standard) Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables-1"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"USER_LABEL_KEY"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"OPERATOR_PLUGINS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"PLACEHOLDER_IMAGE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h4",{id:"removed-cli-options-1"},"Removed CLI Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-clusterId"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.clusterId")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-clusterVersion"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-policyGroup"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-interval"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.schedulingInterval")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logLevel"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"log.level")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logEncoding"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logFile"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-volumeBindTimeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.volumeBindTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-eventChannelCapacity"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.eventChannelCapacity")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-dispatchTimeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.dispatchTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-kubeQPS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.qps")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-kubeBurst"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.burst")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-operatorPlugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-enableConfigHotRefresh"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-disableGangScheduling"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.disableGangScheduling")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-userLabelKey"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-placeHolderImage"),"\nUse ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))),(0,l.yg)("h3",{id:"scheduler-plugin-configuration"},"Scheduler (Plugin) Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables-2"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"USER_LABEL_KEY"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"OPERATOR_PLUGINS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"PLACEHOLDER_IMAGE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h4",{id:"removed-cli-options-2"},"Removed CLI Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-scheduler-name"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-cluster-id"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.clusterId")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-cluster-version"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-policy-group"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},"`--yk-scheduling-interval",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.schedulingInterval")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-config"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use environment: ",(0,l.yg)("inlineCode",{parentName:"li"},"KUBECONFIG")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-level"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"log.level")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-encoding"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-file"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-event-channel-capacity"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.eventChannelCapacity")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-dispatcher-timeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.dispatchTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-qps"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.qps")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-burst"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.burst")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-operator-plugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-enable-config-hot-refresh"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-disable-gang-scheduling"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.disableGangScheduling")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-user-label-key"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-placeholder-image"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h3",{id:"helm-configuration"},"Helm Configuration"),(0,l.yg)("h4",{id:"removed-options"},"Removed Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"userLabelKey"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement")))),(0,l.yg)("h4",{id:"deprecated-options"},"Deprecated Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"operatorPlugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"placeHolderImage"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.processNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.processNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.bypassNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.bypassNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.labelNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.labelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.noLabelNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.noLabelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"configuration"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"queues.yaml"))))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3259ac92.97f1af5c.js b/assets/js/3259ac92.97f1af5c.js new file mode 100644 index 00000000000..d07a9a22ef0 --- /dev/null +++ b/assets/js/3259ac92.97f1af5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[82495],{58860:(e,n,i)=>{i.d(n,{xA:()=>g,yg:()=>d});var a=i(37953);function l(e,n,i){return n in e?Object.defineProperty(e,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[n]=i,e}function r(e,n){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),i.push.apply(i,a)}return i}function t(e){for(var n=1;n=0||(l[i]=e[i]);return l}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(l[i]=e[i])}return l}var p=a.createContext({}),s=function(e){var n=a.useContext(p),i=n;return e&&(i="function"==typeof e?e(n):t(t({},n),e)),i},g=function(e){var n=s(e.components);return a.createElement(p.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},y=a.forwardRef((function(e,n){var i=e.components,l=e.mdxType,r=e.originalType,p=e.parentName,g=o(e,["components","mdxType","originalType","parentName"]),u=s(i),y=l,d=u["".concat(p,".").concat(y)]||u[y]||m[y]||r;return i?a.createElement(d,t(t({ref:n},g),{},{components:i})):a.createElement(d,t({ref:n},g))}));function d(e,n){var i=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var r=i.length,t=new Array(r);t[0]=y;var o={};for(var p in n)hasOwnProperty.call(n,p)&&(o[p]=n[p]);o.originalType=e,o[u]="string"==typeof e?e:l,t[1]=o;for(var s=2;s{i.r(n),i.d(n,{assets:()=>p,contentTitle:()=>t,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>s});var a=i(72994),l=(i(37953),i(58860));const r={id:"config_v2",title:"Configuration V2"},t=void 0,o={unversionedId:"design/config_v2",id:"design/config_v2",title:"Configuration V2",description:"\x3c!--",source:"@site/docs/design/config_v2.md",sourceDirName:"design",slug:"/design/config_v2",permalink:"/docs/next/design/config_v2",draft:!1,tags:[],version:"current",frontMatter:{id:"config_v2",title:"Configuration V2"},sidebar:"docs",previous:{title:"Resilience",permalink:"/docs/next/design/resilience"},next:{title:"Scheduler Configuration",permalink:"/docs/next/design/scheduler_configuration"}},p={},s=[{value:"Introduction",id:"introduction",level:2},{value:"Goals",id:"goals",level:3},{value:"Non-Goals",id:"non-goals",level:3},{value:"References",id:"references",level:3},{value:"Implementation JIRA",id:"implementation-jira",level:4},{value:"Other relevant JIRAs",id:"other-relevant-jiras",level:4},{value:"Services to cover",id:"services-to-cover",level:3},{value:"Services excluded",id:"services-excluded",level:3},{value:"Configuration format",id:"configuration-format",level:2},{value:"Mutability of configuration values",id:"mutability-of-configuration-values",level:3},{value:"Update handling",id:"update-handling",level:3},{value:"Legacy configuration handling",id:"legacy-configuration-handling",level:3},{value:"Environment variables",id:"environment-variables",level:3},{value:"Helm considerations",id:"helm-considerations",level:3},{value:"Core Configuration",id:"core-configuration",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Default ConfigMap",id:"default-configmap",level:3},{value:"Admission Controller Configuration",id:"admission-controller-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables",level:4},{value:"Removed CLI Options",id:"removed-cli-options",level:4},{value:"Scheduler (Standard) Configuration",id:"scheduler-standard-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables-1",level:4},{value:"Removed CLI Options",id:"removed-cli-options-1",level:4},{value:"Scheduler (Plugin) Configuration",id:"scheduler-plugin-configuration",level:3},{value:"Removed Environment Variables",id:"removed-environment-variables-2",level:4},{value:"Removed CLI Options",id:"removed-cli-options-2",level:4},{value:"Helm Configuration",id:"helm-configuration",level:3},{value:"Removed Options",id:"removed-options",level:4},{value:"Deprecated Options",id:"deprecated-options",level:4}],g={toc:s},u="wrapper";function m(e){let{components:n,...i}=e;return(0,l.yg)(u,(0,a.A)({},g,i,{components:n,mdxType:"MDXLayout"}),(0,l.yg)("h2",{id:"introduction"},"Introduction"),(0,l.yg)("p",null,"Over time the YuniKorn configuration has increased in complexity. The current\nconfiguration for YuniKorn is split over a number of different options, file\nand command line, and formats. There is a requirement now to define an overall\nconfiguration approach that can be used for all components."),(0,l.yg)("h3",{id:"goals"},"Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Define a configuration format"),(0,l.yg)("li",{parentName:"ul"},"Define an update and modification strategy"),(0,l.yg)("li",{parentName:"ul"},"Provide consistency between configuration of YuniKorn components"),(0,l.yg)("li",{parentName:"ul"},"Legacy migration strategy")),(0,l.yg)("h3",{id:"non-goals"},"Non-Goals"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Redefine the queue configuration"),(0,l.yg)("li",{parentName:"ul"},"Migration timeline for the old configuration options")),(0,l.yg)("h3",{id:"references"},"References"),(0,l.yg)("h4",{id:"implementation-jira"},"Implementation JIRA"),(0,l.yg)("p",null,(0,l.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-1221"},"YUNIKORN-1221")," - ","[Umbrella]"," Configuration V2"),(0,l.yg)("h4",{id:"other-relevant-jiras"},"Other relevant JIRAs"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-455"},"YUNIKORN-455")," - Make the core configurable"),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1213"},"YUNIKORN-1213")," - Background health checker needs to be configurable"),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1335"},"YUNIKORN-1335")," - Write yunikorn-web error logs to stderr")),(0,l.yg)("h3",{id:"services-to-cover"},"Services to cover"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Scheduler (Standard) - K8Shim + Core"),(0,l.yg)("li",{parentName:"ul"},"Scheduler (Plugin) - K8Shim + Core"),(0,l.yg)("li",{parentName:"ul"},"Admission controller")),(0,l.yg)("h3",{id:"services-excluded"},"Services excluded"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},"Web UI (not needed after ",(0,l.yg)("a",{parentName:"li",href:"https://issues.apache.org/jira/browse/YUNIKORN-1335"},"YUNIKORN-1335"),")")),(0,l.yg)("h2",{id:"configuration-format"},"Configuration format"),(0,l.yg)("p",null,"Currently only Kubernetes is a supported deployment pattern. Future shims may\nneed an alternative configuration syntax. To enable this, we will update the\nscheduler interface to support passing the core configuration (the content of\nthe ",(0,l.yg)("inlineCode",{parentName:"p"},"queues.yaml")," ConfigMap entry) to the core on startup and refresh. The\nexisting config watcher functionality in the core will be removed and the shim\nwill gain the responsibility for watching for ConfigMap changes. The shim\nactually already has this ability now, it is just not used."),(0,l.yg)("p",null,"We will use two ConfigMaps to configure YuniKorn:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"yunikorn-defaults"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"This will be a new ConfigMap written by Helm; it will contain only values\nexplicitly configured by an administrator via Helm variables."))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"yunikorn-configs"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"This ConfigMap will contain overrides for yunikorn-defaults. It was\npreviously a Helm hook in previous YuniKorn releases; it will no longer\nbe managed by Helm and may be updated freely by third-party tools.")))),(0,l.yg)("p",null,"The effective configuration will be the combination of both ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-defaults"),"\nand ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-configs"),", with ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-configs")," taking precedence."),(0,l.yg)("p",null,"Neither ConfigMap (even the existing one) is required for proper functionality.\nIn the case where a ConfigMap does not exist, we will use compiled-in defaults\nfor all options. This enables bootstrapping in a variety of environments,\nincluding local development mode, as the ConfigMap need not exist to bring the\nscheduler components up. Future configuration options should be set via the\nConfigMap exclusively."),(0,l.yg)("h3",{id:"mutability-of-configuration-values"},"Mutability of configuration values"),(0,l.yg)("p",null,"We should strive for hot-reload of all configuration values where possible.\nWhere hot-reload is not implemented, this should be clearly documented. For the\ninitial release, the core config and admission controller will be\nhot-reloadable but many items in the shim will likely not be. The shim was not\ndesigned to hot-reload anything so this will be a large future task. Some items\nmay never be reloadable due to architectural limitations."),(0,l.yg)("h3",{id:"update-handling"},"Update handling"),(0,l.yg)("p",null,"Given the security issues involved with updates, the default Kubernetes access\ncontrol alone should be used for ConfigMap updates. We can still syntax-check\nthe core side of the configuration in the admission controller as before.\nPartial updates are allowed as Kubernetes supports patching of ConfigMaps."),(0,l.yg)("h3",{id:"legacy-configuration-handling"},"Legacy configuration handling"),(0,l.yg)("p",null,"Helm will be updated to render all existing legacy options into the\n",(0,l.yg)("inlineCode",{parentName:"p"},"yunikorn-defaults")," ConfigMap for easier transition to the new configuration\nformat. Consequently, it is not necessary for YuniKorn components to parse the\nold environment and command-line arguments."),(0,l.yg)("h3",{id:"environment-variables"},"Environment variables"),(0,l.yg)("p",null,"All environment variables for all services will be removed, with the exception\nof:"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"NAMESPACE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Default value: ",(0,l.yg)("inlineCode",{parentName:"li"},"default")),(0,l.yg)("li",{parentName:"ul"},"Will be auto-populated from Helm and resolve to the pod's running\nnamespace"),(0,l.yg)("li",{parentName:"ul"},"Needed so that YuniKorn can determine what namespace it was launched in"),(0,l.yg)("li",{parentName:"ul"},"Should only be provided explicitly at development time"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"KUBECONFIG"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Default value: ",(0,l.yg)("inlineCode",{parentName:"li"},"$HOME/.kube/config")),(0,l.yg)("li",{parentName:"ul"},"Will be ignored if running inside Kubernetes; in-cluster configuration\nwill be used in that case"),(0,l.yg)("li",{parentName:"ul"},"Needed so that we can bootstrap to K8s and load the YuniKorn ConfigMap at\nruntime"),(0,l.yg)("li",{parentName:"ul"},"Should only be provided explicitly at development time")))),(0,l.yg)("h3",{id:"helm-considerations"},"Helm considerations"),(0,l.yg)("p",null,"All configuration options which have moved into the ConfigMap will be marked as\ndeprecated in the Helm chart documentation. Their replacement is the more\ngeneric ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikornDefaults")," dictionary. If the legacy values are present but\nthe associated ",(0,l.yg)("inlineCode",{parentName:"p"},"yunikornDefaults")," entry is missing, the legacy configuration\nvalue will be used. This will allow users some time to migrate to the new\nconfiguration style. The legacy attributes will be removed in a future release."),(0,l.yg)("h3",{id:"core-configuration"},"Core Configuration"),(0,l.yg)("p",null,"The core scheduler configuration is loaded from the ",(0,l.yg)("inlineCode",{parentName:"p"},"queues.yaml")," section of\nthe ConfigMap, assuming ",(0,l.yg)("inlineCode",{parentName:"p"},"service.policyGroup")," is set to the default value\n",(0,l.yg)("inlineCode",{parentName:"p"},"queues"),". If the policy group has been customized, core scheduler configuration\nwill be read from ",(0,l.yg)("inlineCode",{parentName:"p"},"{service.policyGroup}.yaml"),". This section is special as its\ncontents are passed directly to the core for evaluation and update and is not\nread directly by the shim. The content of this section is unchanged from prior\nreleases."),(0,l.yg)("h2",{id:"appendix"},"Appendix"),(0,l.yg)("h3",{id:"default-configmap"},"Default ConfigMap"),(0,l.yg)("p",null,"If not present, the default ConfigMap will resolve to these defaults.\nAdditionally, individual options will resolve to those listed here if not\nspecified. Note that these values are subject to change in future releases."),(0,l.yg)("pre",null,(0,l.yg)("code",{parentName:"pre"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: yunikorn-configs\ndata:\n service.clusterId: "mycluster"\n service.policyGroup: "queues"\n service.schedulingInterval: "1s"\n service.volumeBindTimeout: "10s"\n service.eventChannelCapacity: "1048576"\n service.dispatchTimeout: "5m"\n service.operatorPlugins: "general"\n service.disableGangScheduling: "false"\n service.enableConfigHotRefresh: "true"\n service.placeholderImage: "registry.k8s.io/pause:3.7"\n service.instanceTypeNodeLabelKey: "node.kubernetes.io/instance-type"\n health.checkInterval: "30s"\n log.level: "0"\n kubernetes.qps: "1000"\n kubernetes.burst: "1000"\n admissionController.webHook.amServiceName: "yunikorn-admission-controller-service"\n admissionController.webHook.schedulerServiceAddress: "yunikorn-service:9080"\n admissionController.filtering.processNamespaces: ""\n admissionController.filtering.bypassNamespaces: "^kube-system$"\n admissionController.filtering.labelNamespaces: ""\n admissionController.filtering.noLabelNamespaces: ""\n admissionController.accessControl.bypassAuth: "false"\n admissionController.accessControl.trustControllers: "true"\n admissionController.accessControl.systemUsers: "^system:serviceaccount:kube-system:"\n admissionController.accessControl.externalUsers: ""\n admissionController.accessControl.externalGroups: ""\n queues.yaml: |\n partitions:\n - name: default\n placementrules:\n - name: tag\n value: namespace\n create: true\n queues:\n - name: root\n submitacl: \'*\'`\n')),(0,l.yg)("h3",{id:"admission-controller-configuration"},"Admission Controller Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"POLICY_GROUP"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ENABLE_CONFIG_HOT_REFRESH"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"SCHEDULER_SERVICE_ADDRESS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.webHook.schedulerServiceAddress")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_SERVICE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.webHook.amServiceName")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_NAMESPACE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use Environment variable: ",(0,l.yg)("inlineCode",{parentName:"li"},"NAMESPACE")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_PROCESS_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.processNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_BYPASS_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.bypassNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSON_CONTROLLER_LABEL_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.labelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"ADMISSION_CONTROLLER_NO_LABEL_NAMESPACES"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.noLabelNamespaces"))))),(0,l.yg)("h4",{id:"removed-cli-options"},"Removed CLI Options"),(0,l.yg)("p",null,"None"),(0,l.yg)("h3",{id:"scheduler-standard-configuration"},"Scheduler (Standard) Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables-1"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"USER_LABEL_KEY"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"OPERATOR_PLUGINS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"PLACEHOLDER_IMAGE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h4",{id:"removed-cli-options-1"},"Removed CLI Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-clusterId"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.clusterId")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-clusterVersion"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-policyGroup"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-interval"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.schedulingInterval")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logLevel"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"log.level")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logEncoding"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-logFile"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-volumeBindTimeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.volumeBindTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-eventChannelCapacity"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.eventChannelCapacity")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-dispatchTimeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.dispatchTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-kubeQPS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.qps")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-kubeBurst"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.burst")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-operatorPlugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-enableConfigHotRefresh"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-disableGangScheduling"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.disableGangScheduling")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-userLabelKey"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"-placeHolderImage"),"\nUse ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))),(0,l.yg)("h3",{id:"scheduler-plugin-configuration"},"Scheduler (Plugin) Configuration"),(0,l.yg)("h4",{id:"removed-environment-variables-2"},"Removed Environment Variables"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"USER_LABEL_KEY"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"OPERATOR_PLUGINS"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"PLACEHOLDER_IMAGE"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h4",{id:"removed-cli-options-2"},"Removed CLI Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-scheduler-name"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-cluster-id"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.clusterId")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-cluster-version"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-policy-group"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.policyGroup")))),(0,l.yg)("li",{parentName:"ul"},"`--yk-scheduling-interval",(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.schedulingInterval")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-config"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use environment: ",(0,l.yg)("inlineCode",{parentName:"li"},"KUBECONFIG")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-level"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"log.level")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-encoding"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-log-file"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-event-channel-capacity"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.eventChannelCapacity")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-dispatcher-timeout"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.dispatchTimeout")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-qps"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.qps")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-kube-burst"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"kubernetes.burst")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-operator-plugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-enable-config-hot-refresh"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.enableConfigHotRefresh")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-disable-gang-scheduling"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.disableGangScheduling")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-user-label-key"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement"))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"--yk-placeholder-image"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage"))))),(0,l.yg)("h3",{id:"helm-configuration"},"Helm Configuration"),(0,l.yg)("h4",{id:"removed-options"},"Removed Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"userLabelKey"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"No replacement")))),(0,l.yg)("h4",{id:"deprecated-options"},"Deprecated Options"),(0,l.yg)("ul",null,(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"operatorPlugins"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.operatorPlugins")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"placeHolderImage"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"service.placeholderImage")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.processNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.processNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.bypassNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.bypassNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.labelNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.labelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.noLabelNamespaces"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"admissionController.filtering.noLabelNamespaces")))),(0,l.yg)("li",{parentName:"ul"},(0,l.yg)("inlineCode",{parentName:"li"},"configuration"),(0,l.yg)("ul",{parentName:"li"},(0,l.yg)("li",{parentName:"ul"},"Use ConfigMap: ",(0,l.yg)("inlineCode",{parentName:"li"},"queues.yaml"))))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6bf8e8e6.81127173.js b/assets/js/6bf8e8e6.81127173.js new file mode 100644 index 00000000000..7ce316f6c84 --- /dev/null +++ b/assets/js/6bf8e8e6.81127173.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[13843],{58860:(e,n,a)=>{a.d(n,{xA:()=>u,yg:()=>m});var r=a(37953);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function t(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,r)}return a}function s(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=r.createContext({}),p=function(e){var n=r.useContext(l),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},u=function(e){var n=p(e.components);return r.createElement(l.Provider,{value:n},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var a=e.components,o=e.mdxType,t=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=p(a),d=o,m=c["".concat(l,".").concat(d)]||c[d]||g[d]||t;return a?r.createElement(m,s(s({ref:n},u),{},{components:a})):r.createElement(m,s({ref:n},u))}));function m(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var t=a.length,s=new Array(t);s[0]=d;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[c]="string"==typeof e?e:o,s[1]=i;for(var p=2;p{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>t,metadata:()=>i,toc:()=>p});var r=a(72994),o=(a(37953),a(58860));const t={id:"scheduler",title:"Scheduler"},s=void 0,i={unversionedId:"api/scheduler",id:"api/scheduler",title:"Scheduler",description:"\x3c!--",source:"@site/docs/api/scheduler.md",sourceDirName:"api",slug:"/api/scheduler",permalink:"/docs/next/api/scheduler",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler",title:"Scheduler"},sidebar:"docs",previous:{title:"Cluster",permalink:"/docs/next/api/cluster"},next:{title:"System",permalink:"/docs/next/api/system"}},l={},p=[{value:"Partitions",id:"partitions",level:2},{value:"Success response",id:"success-response",level:3},{value:"Error response",id:"error-response",level:3},{value:"Queues",id:"queues",level:2},{value:"Partition queues",id:"partition-queues",level:3},{value:"Success response",id:"success-response-1",level:3},{value:"Error response",id:"error-response-1",level:3},{value:"Applications",id:"applications",level:2},{value:"Partition applications",id:"partition-applications",level:3},{value:"Success response",id:"success-response-2",level:3},{value:"Queue applications",id:"queue-applications",level:3},{value:"Success response",id:"success-response-3",level:3},{value:"Error response",id:"error-response-2",level:3},{value:"Application",id:"application",level:2},{value:"Partition/Queue application",id:"partitionqueue-application",level:3},{value:"Success response",id:"success-response-4",level:3},{value:"Error response",id:"error-response-3",level:3},{value:"UsersTracker",id:"userstracker",level:2},{value:"Get users usage tracking information",id:"get-users-usage-tracking-information",level:3},{value:"Success response",id:"success-response-5",level:3},{value:"Error response",id:"error-response-4",level:3},{value:"UserTracker",id:"usertracker",level:2},{value:"Get specific user usage tracking information",id:"get-specific-user-usage-tracking-information",level:3},{value:"Success response",id:"success-response-6",level:3},{value:"Error response",id:"error-response-5",level:3},{value:"GroupsTracker",id:"groupstracker",level:2},{value:"Get groups usage tracking information",id:"get-groups-usage-tracking-information",level:3},{value:"Success response",id:"success-response-7",level:3},{value:"Error response",id:"error-response-6",level:3},{value:"GroupTracker",id:"grouptracker",level:2},{value:"Get specific group usage tracking information",id:"get-specific-group-usage-tracking-information",level:3},{value:"Success response",id:"success-response-8",level:3},{value:"Error response",id:"error-response-7",level:3},{value:"Nodes",id:"nodes",level:2},{value:"Partition nodes",id:"partition-nodes",level:3},{value:"Success response",id:"success-response-9",level:3},{value:"Error response",id:"error-response-8",level:3},{value:"Node",id:"node",level:2},{value:"Partition node",id:"partition-node",level:3},{value:"Success response",id:"success-response-10",level:3},{value:"Error response",id:"error-response-9",level:3},{value:"Node utilization",id:"node-utilization",level:2},{value:"Success response",id:"success-response-11",level:3},{value:"Error response",id:"error-response-10",level:3},{value:"Node utilizations",id:"node-utilizations",level:2},{value:"Success response",id:"success-response-12",level:3},{value:"Error response",id:"error-response-11",level:3},{value:"Goroutines info",id:"goroutines-info",level:2},{value:"Success response",id:"success-response-13",level:3},{value:"Error response",id:"error-response-12",level:3},{value:"Metrics",id:"metrics",level:2},{value:"Success response",id:"success-response-14",level:3},{value:"Configuration validation",id:"configuration-validation",level:2},{value:"Success response",id:"success-response-15",level:3},{value:"Allowed configuration",id:"allowed-configuration",level:4},{value:"Disallowed configuration",id:"disallowed-configuration",level:4},{value:"Configuration",id:"configuration",level:2},{value:"Success response",id:"success-response-16",level:3},{value:"Application history",id:"application-history",level:2},{value:"Success response",id:"success-response-17",level:3},{value:"Error response",id:"error-response-13",level:3},{value:"Container history",id:"container-history",level:2},{value:"Success response",id:"success-response-18",level:3},{value:"Error response",id:"error-response-14",level:3},{value:"Endpoint healthcheck",id:"endpoint-healthcheck",level:2},{value:"Success response",id:"success-response-19",level:3},{value:"Retrieve full state dump",id:"retrieve-full-state-dump",level:2},{value:"Success response",id:"success-response-20",level:3},{value:"Failure response",id:"failure-response",level:3},{value:"Batch Events",id:"batch-events",level:2},{value:"Success response",id:"success-response-21",level:3},{value:"Error response",id:"error-response-15",level:3},{value:"Event stream",id:"event-stream",level:3},{value:"Success response",id:"success-response-22",level:3},{value:"Error responses",id:"error-responses",level:3}],u={toc:p},c="wrapper";function g(e){let{components:n,...a}=e;return(0,o.yg)(c,(0,r.A)({},u,a,{components:n,mdxType:"MDXLayout"}),(0,o.yg)("h1",{id:"overview"},"Overview"),(0,o.yg)("p",null,"The scheduler REST API returns information about various objects used by the YuniKorn Scheduler."),(0,o.yg)("p",null,"Many of these APIs return collections of resources. Internally, all resources are represented as raw\n64-bit signed integer types. When interpreting responses from the REST API, resources of type ",(0,o.yg)("inlineCode",{parentName:"p"},"memory"),"\nare returned in units of bytes while resources of type ",(0,o.yg)("inlineCode",{parentName:"p"},"vcore")," are returned in units of millicores\n(thousands of a core). All other resource types have no specific unit assigned."),(0,o.yg)("p",null,"Under the ",(0,o.yg)("inlineCode",{parentName:"p"},"allocations")," field in the response content for the app/node-related calls in the following spec, ",(0,o.yg)("inlineCode",{parentName:"p"},"placeholderUsed")," refers to whether or not the allocation is a replacement for a placeholder. If true, ",(0,o.yg)("inlineCode",{parentName:"p"},"requestTime")," is the creation time of its placeholder allocation, otherwise it's that of the allocation's ask. ",(0,o.yg)("inlineCode",{parentName:"p"},"allocationTime")," is the creation time of the allocation, and ",(0,o.yg)("inlineCode",{parentName:"p"},"allocationDelay")," is simply the difference between ",(0,o.yg)("inlineCode",{parentName:"p"},"allocationTime")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"requestTime"),"."),(0,o.yg)("h2",{id:"partitions"},"Partitions"),(0,o.yg)("p",null,"Returns general information and statistics about a partition."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partitions")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "clusterId": "mycluster",\n "name": "default",\n "state": "Active",\n "lastStateTransitionTime": 1649167576110754000,\n "capacity": {\n "capacity": {\n "ephemeral-storage": 188176871424,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 1000000000,\n "pods": 330,\n "vcore": 1000\n },\n "usedCapacity": {\n "memory": 800000000,\n "vcore": 500\n },\n "utilization": {\n "memory": 80,\n "vcore": 50\n }\n },\n "nodeSortingPolicy": {\n "type": "fair",\n "resourceWeights": {\n "memory": 1.5,\n "vcore": 1.3\n }\n },\n "applications": {\n "New": 5,\n "Pending": 5,\n "total": 10\n },\n "totalContainers": 0,\n "totalNodes": 2\n },\n {\n "clusterId": "mycluster",\n "name": "gpu",\n "state": "Active",\n "lastStateTransitionTime": 1649167576111236000,\n "capacity": {\n "capacity": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "usedCapacity": {\n "memory": 500000000,\n "vcore": 300\n },\n "utilization": {\n "memory": 25,\n "vcore": 15\n }\n },\n "nodeSortingPolicy": {\n "type": "binpacking",\n "resourceWeights": {\n "memory": 0,\n "vcore": 4.11\n }\n },\n "applications": {\n "New": 5,\n "Running": 10,\n "Pending": 5,\n "total": 20\n },\n "totalContainers": 20,\n "totalNodes": 5\n }\n]\n')),(0,o.yg)("h3",{id:"error-response"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"queues"},"Queues"),(0,o.yg)("h3",{id:"partition-queues"},"Partition queues"),(0,o.yg)("p",null,"Fetch all Queues associated with given Partition and displays general information about the queues like name, status, capacities and properties.\nThe queues' hierarchy is kept in the response json. "),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queues")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-1"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("p",null,"For the default queue hierarchy (only ",(0,o.yg)("inlineCode",{parentName:"p"},"root.default")," leaf queue exists) a similar response to the following is sent back to the client:"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "queuename": "root",\n "status": "Active",\n "maxResource": {\n "ephemeral-storage": 188176871424,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 8000000000,\n "pods": 330,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "allocatedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "pendingResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "isLeaf": "false",\n "isManaged": "false",\n "properties": {\n "application.sort.policy": "stateaware"\n },\n "parent": "",\n "template": {\n "maxResource": {\n "memory": 8000000000,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "properties": {\n "application.sort.policy": "stateaware"\n }\n },\n "partition": "default",\n "children": [\n {\n "queuename": "root.default",\n "status": "Active",\n "maxResource": {\n "memory": 8000000000,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "allocatedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "pendingResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "isLeaf": "true",\n "isManaged": "false",\n "properties": {\n "application.sort.policy": "stateaware"\n },\n "parent": "root",\n "template": null,\n "children": [],\n "absUsedCapacity": {\n "memory": 1,\n "vcore": 0\n },\n "maxRunningApps": 12,\n "runningApps": 4,\n "allocatingAcceptedApps": [\n "app-1",\n "app-2"\n ]\n }\n ],\n "absUsedCapacity": {\n "memory": 1,\n "vcore": 0\n }\n } \n]\n')),(0,o.yg)("h3",{id:"error-response-1"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"applications"},"Applications"),(0,o.yg)("h3",{id:"partition-applications"},"Partition applications"),(0,o.yg)("p",null,"Fetch all Applications for the given Partition/State combination and displays general information about the applications like used resources, queue name, submission time and allocations.\nOnly following application states are allowed: active, rejected, completed. Active is a fake state that represents all application states except completed and rejected.\nFor active state, can narrow the result by status query parameters(case-insensitive). For example, can fetch ",(0,o.yg)("inlineCode",{parentName:"p"},"Running")," applications for the default partition by\n",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/default/applications/active?status=running"),"."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/:partition/applications/:state")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-2"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("p",null,"The content of the application object is the same as Queue Applications. See\n",(0,o.yg)("a",{parentName:"p",href:"#queue-applications"},"Queue Applications")," for details."),(0,o.yg)("h3",{id:"queue-applications"},"Queue applications"),(0,o.yg)("p",null,"Fetch all Applications for the given Partition/Queue combination and displays general information about the applications like used resources, queue name, submission time and allocations."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queue/{queueName}/applications")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-3"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Deprecated"),":"),(0,o.yg)("p",null,"Field ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid")," has been deprecated, would be removed from below response in YUNIKORN 1.7.0 release. ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," has replaced ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid"),". Both ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," fields have the same value. ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," has extra suffix containing hyphen and counter (-0, -1 and so on) at the end. "),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("p",null,"In the example below there are three allocations belonging to two applications, one with a pending request."),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "applicationID": "application-0001",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [\n {\n "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task2"\n },\n "requestTime": 16487540320812345678,\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingCount": 1,\n "priority": "0",\n "requiredNodeId": "",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderTimeout": 0,\n "taskGroupName": "",\n "allocationLog": [\n {\n "message": "node(s) didn\'t match Pod\'s node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate",\n "lastOccurrence": 16487540320812346001,\n "count": 81\n },\n {\n "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate, node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346002,\n "count": 504\n },\n {\n "message": "node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346003,\n "count": 1170\n }\n ]\n }\n ],\n "allocations": [\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": true\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [\n {\n "taskGroupName": "task-group-example",\n "count": 2,\n "minResource": {\n "memory": 1000000000,\n "vcore": 100\n },\n "replaced": 1,\n "timedout": 1\n }\n ],\n "hasReserved": false,\n "reservations": []\n },\n {\n "applicationID": "application-0002",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [],\n "allocations": [\n {\n "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID": "08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n },\n {\n "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task1"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b",\n "allocationID": "96beeb45-5ed2-4c19-9a83-2ac807637b3b-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0002",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [],\n "hasReserved": false,\n "reservations": []\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-2"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"application"},"Application"),(0,o.yg)("h3",{id:"partitionqueue-application"},"Partition/Queue application"),(0,o.yg)("p",null,"Fetch an Application given a Partition, Queue(optional) and Application ID and displays general information about the application like used resources, queue name, submission time and allocations."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/application/{appId}")," or ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queue/{queueName}/application/{appId}")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-4"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Deprecated"),":"),(0,o.yg)("p",null,"Field ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid")," has been deprecated, would be removed from below response in YUNIKORN 1.7.0 release. ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," has replaced ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid"),". Both ",(0,o.yg)("inlineCode",{parentName:"p"},"uuid")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," fields have the same value. ",(0,o.yg)("inlineCode",{parentName:"p"},"AllocationID")," has extra suffix containing hyphen and counter (-0, -1 and so on) at the end."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "applicationID": "application-0001",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [\n {\n "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task2"\n },\n "requestTime": 16487540320812345678,\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingCount": 1,\n "priority": "0",\n "requiredNodeId": "",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderTimeout": 0,\n "taskGroupName": "",\n "allocationLog": [\n {\n "message": "node(s) didn\'t match Pod\'s node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate",\n "lastOccurrence": 16487540320812346001,\n "count": 81\n },\n {\n "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate, node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346002,\n "count": 504\n },\n {\n "message": "node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346003,\n "count": 1170\n }\n ]\n }\n ],\n "allocations": [\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": true\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [\n {\n "taskGroupName": "task-group-example",\n "count": 2,\n "minResource": {\n "memory": 1000000000,\n "vcore": 100\n },\n "replaced": 1,\n "timedout": 1\n }\n ],\n "hasReserved": false,\n "reservations": []\n}\n')),(0,o.yg)("h3",{id:"error-response-3"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"userstracker"},"UsersTracker"),(0,o.yg)("h3",{id:"get-users-usage-tracking-information"},"Get users usage tracking information"),(0,o.yg)("p",null,"Fetch all users usage given a Partition and displays general information about the users managed by YuniKorn."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/users")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-5"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "userName": "user1",\n "groups": {\n "app2": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n },\n {\n "userName": "user2",\n "groups": {\n "app1": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 11000000000,\n "vcore": 10000\n },\n "runningApplications": ["app1", "app2", "app3"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 5000000000,\n "vcore": 5000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "runningApplications": [\n "app3"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-4"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"usertracker"},"UserTracker"),(0,o.yg)("h3",{id:"get-specific-user-usage-tracking-information"},"Get specific user usage tracking information"),(0,o.yg)("p",null,"Fetch specific user usage given a Partition and displays general information about the users managed by YuniKorn."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/user/{userName}")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-6"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "userName": "user1",\n "groups": {\n "app1": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n}\n')),(0,o.yg)("h3",{id:"error-response-5"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"groupstracker"},"GroupsTracker"),(0,o.yg)("h3",{id:"get-groups-usage-tracking-information"},"Get groups usage tracking information"),(0,o.yg)("p",null,"Fetch all groups usage given a Partition and displays general information about the groups managed by YuniKorn."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/groups")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-7"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "groupName": "group1",\n "applications": ["app1", "app2"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n },\n {\n "groupName": "group2",\n "applications": ["app1", "app2", "app3"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 11000000000,\n "vcore": 10000\n },\n "runningApplications": ["app1", "app2", "app3"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 5000000000,\n "vcore": 5000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "runningApplications": [\n "app3"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-6"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"grouptracker"},"GroupTracker"),(0,o.yg)("h3",{id:"get-specific-group-usage-tracking-information"},"Get specific group usage tracking information"),(0,o.yg)("p",null,"Fetch specific group usage given a Partition and displays general information about the groups managed by YuniKorn."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/group/{groupName}")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-8"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "groupName": "group1",\n "applications": ["app1", "app2"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n}\n')),(0,o.yg)("h3",{id:"error-response-7"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"nodes"},"Nodes"),(0,o.yg)("h3",{id:"partition-nodes"},"Partition nodes"),(0,o.yg)("p",null,"Fetch all Nodes associated with given Partition and displays general information about the nodes managed by YuniKorn.\nNode details include host and rack name, capacity, resources, utilization, and allocations."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/nodes")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-9"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("p",null,"Here you can see an example response from a 2-node cluster having 3 allocations."),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "nodeID": "node-0001",\n "hostName": "",\n "rackName": "",\n "attributes": {\n "beta.kubernetes.io/arch": "amd64",\n "beta.kubernetes.io/os": "linux",\n "kubernetes.io/arch": "amd64",\n "kubernetes.io/hostname": "node-0001",\n "kubernetes.io/os": "linux",\n "node-role.kubernetes.io/control-plane": "",\n "node-role.kubernetes.io/master": "",\n "node.kubernetes.io/exclude-from-external-load-balancers": "",\n "ready": "true",\n "si.io/hostname": "node-0001",\n "si.io/rackname": "/rack-default",\n "si/instance-type": "",\n "si/node-partition": "[mycluster]default"\n },\n "capacity": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 14577000000,\n "pods": 110,\n "vcore": 10000\n },\n "allocated": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "occupied": {\n "memory": 154000000,\n "vcore" :750\n },\n "available": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 6423000000,\n "pods": 110,\n "vcore": 1250\n },\n "utilized": {\n "memory": 3,\n "vcore": 13\n },\n "allocations": [\n {\n "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID": "08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n },\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "schedulable": true\n },\n {\n "nodeID": "node-0002",\n "hostName": "",\n "rackName": "",\n "attributes": {\n "beta.kubernetes.io/arch": "amd64",\n "beta.kubernetes.io/os": "linux",\n "kubernetes.io/arch": "amd64",\n "kubernetes.io/hostname": "node-0002",\n "kubernetes.io/os": "linux",\n "ready": "false",\n "si.io/hostname": "node-0002",\n "si.io/rackname": "/rack-default",\n "si/instance-type": "",\n "si/node-partition": "[mycluster]default"\n },\n "capacity": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 14577000000,\n "pods": 110,\n "vcore": 10000\n },\n "allocated": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "occupied": {\n "memory": 154000000,\n "vcore" :750\n },\n "available": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 6423000000,\n "pods": 110,\n "vcore": 1250\n },\n "utilized": {\n "memory": 8,\n "vcore": 38\n },\n "allocations": [\n {\n "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task1"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b",\n "allocationID": "96beeb45-5ed2-4c19-9a83-2ac807637b3b-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0002",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "schedulable": true,\n "isReserved": false,\n "reservations": []\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-8"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"node"},"Node"),(0,o.yg)("h3",{id:"partition-node"},"Partition node"),(0,o.yg)("p",null,"Fetch a Node associated with given Partition and Node ID and displays general information about the node managed by YuniKorn.\nNode details include host and rack name, capacity, resources, utilization, and allocations."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/node/{nodeId}")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-10"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "nodeID":"node-0001",\n "hostName":"",\n "rackName":"",\n "capacity":{\n "ephemeral-storage":75850798569,\n "hugepages-1Gi":0,\n "hugepages-2Mi":0,\n "memory":14577000000,\n "pods":110,\n "vcore":10000\n },\n "allocated":{\n "memory":6000000000,\n "vcore":6000\n },\n "occupied":{\n "memory":154000000,\n "vcore":750\n },\n "available":{\n "ephemeral-storage":75850798569,\n "hugepages-1Gi":0,\n "hugepages-2Mi":0,\n "memory":6423000000,\n "pods":110,\n "vcore":1250\n },\n "utilized":{\n "memory":3,\n "vcore":13\n },\n "allocations":[\n {\n "allocationKey":"54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags":{\n "kubernetes.io/label/app":"sleep",\n "kubernetes.io/label/applicationId":"application-0001",\n "kubernetes.io/label/queue":"root.default",\n "kubernetes.io/meta/namespace":"default",\n "kubernetes.io/meta/podName":"task0"\n },\n "requestTime":1648754034098912461,\n "allocationTime":1648754035973982920,\n "allocationDelay":1875070459,\n "uuid":"08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID":"08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource":{\n "memory":2000000000,\n "vcore":2000\n },\n "priority":"0",\n "nodeId":"node-0001",\n "applicationId":"application-0001",\n "partition":"default",\n "placeholder":false,\n "placeholderUsed":false\n },\n {\n "allocationKey":"deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags":{\n "kubernetes.io/label/app":"sleep",\n "kubernetes.io/label/applicationId":"application-0002",\n "kubernetes.io/label/queue":"root.default",\n "kubernetes.io/meta/namespace":"default",\n "kubernetes.io/meta/podName":"task0"\n },\n "requestTime":1648754034098912461,\n "allocationTime":1648754035973982920,\n "allocationDelay":1875070459,\n "uuid":"9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID":"9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource":{\n "memory":4000000000,\n "vcore":4000\n },\n "priority":"0",\n "nodeId":"node-0001",\n "applicationId":"application-0002",\n "partition":"default",\n "placeholder":false,\n "placeholderUsed":false\n }\n ],\n "schedulable":true\n}\n')),(0,o.yg)("h3",{id:"error-response-9"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"node-utilization"},"Node utilization"),(0,o.yg)("p",null,"Show how every node is distributed with regard to dominant resource utilization."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Status")," : Deprecated since v1.5.0 and will be removed in the next major release. Replaced with ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilizations"),"."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilization")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-11"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "type": "vcore",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 1,\n "nodeNames": [\n "aethergpu"\n ]\n },\n {\n "bucketName": "10-20%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n ... \n ]\n}\n')),(0,o.yg)("h3",{id:"error-response-10"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"node-utilizations"},"Node utilizations"),(0,o.yg)("p",null,"Show the nodes utilization of different types of resources in a cluster."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilizations")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-12"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "clusterId": "mycluster",\n "partition": "default",\n "utilizations": [\n {\n "type": "pods",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n {\n "bucketName": "10-20%"\n },\n ...\n ]\n },\n {\n "type": "vcores",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n {\n "bucketName": "10-20%"\n },\n ...\n ]\n },\n ...\n ]\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-11"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"goroutines-info"},"Goroutines info"),(0,o.yg)("p",null,"Dumps the stack traces of the currently running goroutines."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/stack")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-13"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-text"},"goroutine 356 [running\n]:\ngithub.com/apache/yunikorn-core/pkg/webservice.getStackInfo.func1(0x30a0060,\n0xc003e900e0,\n0x2)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 41 +0xab\ngithub.com/apache/yunikorn-core/pkg/webservice.getStackInfo(0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 48 +0x71\nnet/http.HandlerFunc.ServeHTTP(0x2df0e10,\n0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /usr/local/go/src/net/http/server.go: 1995 +0x52\ngithub.com/apache/yunikorn-core/pkg/webservice.Logger.func1(0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/webservice.go: 65 +0xd4\nnet/http.HandlerFunc.ServeHTTP(0xc00003a570,\n0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /usr/local/go/src/net/http/server.go: 1995 +0x52\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc00029cb40,\n0x30a0060,\n0xc003e900e0,\n0xc0063fee00)\n /yunikorn/go/pkg/mod/github.com/gorilla/mux@v1.7.3/mux.go: 212 +0x140\nnet/http.serverHandler.ServeHTTP(0xc0000df520,\n0x30a0060,\n0xc003e900e0,\n0xc0063fee00)\n /usr/local/go/src/net/http/server.go: 2774 +0xcf\nnet/http.(*conn).serve(0xc0000eab40,\n0x30a61a0,\n0xc003b74000)\n /usr/local/go/src/net/http/server.go: 1878 +0x812\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go: 2884 +0x4c5\n\ngoroutine 1 [chan receive,\n 26 minutes\n]:\nmain.main()\n /yunikorn/pkg/shim/main.go: 52 +0x67a\n\ngoroutine 19 [syscall,\n 26 minutes\n]:\nos/signal.signal_recv(0x1096f91)\n /usr/local/go/src/runtime/sigqueue.go: 139 +0x9f\nos/signal.loop()\n /usr/local/go/src/os/signal/signal_unix.go: 23 +0x30\ncreated by os/signal.init.0\n /usr/local/go/src/os/signal/signal_unix.go: 29 +0x4f\n\n...\n")),(0,o.yg)("h3",{id:"error-response-12"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"metrics"},"Metrics"),(0,o.yg)("p",null,"Endpoint to retrieve metrics from the Prometheus server.\nThe metrics are dumped with help messages and type information."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/metrics")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-14"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-text"},'# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n# TYPE go_gc_duration_seconds summary\ngo_gc_duration_seconds{quantile="0"} 2.567e-05\ngo_gc_duration_seconds{quantile="0.25"} 3.5727e-05\ngo_gc_duration_seconds{quantile="0.5"} 4.5144e-05\ngo_gc_duration_seconds{quantile="0.75"} 6.0024e-05\ngo_gc_duration_seconds{quantile="1"} 0.00022528\ngo_gc_duration_seconds_sum 0.021561648\ngo_gc_duration_seconds_count 436\n# HELP go_goroutines Number of goroutines that currently exist.\n# TYPE go_goroutines gauge\ngo_goroutines 82\n# HELP go_info Information about the Go environment.\n# TYPE go_info gauge\ngo_info{version="go1.12.17"} 1\n# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.\n# TYPE go_memstats_alloc_bytes gauge\ngo_memstats_alloc_bytes 9.6866248e+07\n\n...\n\n# HELP yunikorn_scheduler_vcore_nodes_usage Nodes resource usage, by resource name.\n# TYPE yunikorn_scheduler_vcore_nodes_usage gauge\nyunikorn_scheduler_vcore_nodes_usage{range="(10%, 20%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(20%,30%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(30%,40%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(40%,50%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(50%,60%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(60%,70%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(70%,80%]"} 1\nyunikorn_scheduler_vcore_nodes_usage{range="(80%,90%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(90%,100%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="[0,10%]"} 0\n')),(0,o.yg)("h2",{id:"configuration-validation"},"Configuration validation"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/validate-conf")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"POST")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-15"},"Success response"),(0,o.yg)("p",null,"Regardless whether the configuration is allowed or not if the server was able to process the request, it will yield a 200 HTTP status code."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("h4",{id:"allowed-configuration"},"Allowed configuration"),(0,o.yg)("p",null,"Sending the following simple configuration yields an accept"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: test\n")),(0,o.yg)("p",null,"Reponse"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "allowed": true,\n "reason": ""\n}\n')),(0,o.yg)("h4",{id:"disallowed-configuration"},"Disallowed configuration"),(0,o.yg)("p",null,'The following configuration is not allowed due to the "wrong_text" field put into the yaml file.'),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: test\n - wrong_text\n")),(0,o.yg)("p",null,"Reponse"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "allowed": false,\n "reason": "yaml: unmarshal errors:\\n line 7: cannot unmarshal !!str `wrong_text` into configs.PartitionConfig"\n}\n')),(0,o.yg)("h2",{id:"configuration"},"Configuration"),(0,o.yg)("p",null,"Endpoint to retrieve the current scheduler configuration"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/config")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-16"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example (with ",(0,o.yg)("inlineCode",{parentName:"strong"},"Accept: application/json")," header)")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "Partitions": [\n {\n "Name": "default",\n "Queues": [\n {\n "Name": "root",\n "Parent": true,\n "Resources": {},\n "SubmitACL": "*",\n "ChildTemplate": {\n "Resources": {}\n }\n }\n ],\n "PlacementRules": [\n {\n "Name": "tag",\n "Create": true,\n "Filter": {\n "Type": ""\n },\n "Value": "namespace"\n }\n ],\n "Preemption": {\n "Enabled": false\n },\n "NodeSortPolicy": {\n "Type": ""\n }\n }\n ],\n "Checksum": "FD5D3726DF0F02416E02F3919D78F61B15D14425A34142D93B24C137ED056946",\n "Extra": {\n "event.trackingEnabled": "false",\n "log.core.scheduler.level": "info",\n "log.core.security.level": "info",\n "log.level": "debug"\n }\n}\n')),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content example (without ",(0,o.yg)("inlineCode",{parentName:"strong"},"Accept: application/json")," header)")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},'partitions:\n - name: default\n queues:\n - name: root\n parent: true\n submitacl: "*"\n placementrules:\n - name: tag\n create: true\n value: namespace\nchecksum: FD5D3726DF0F02416E02F3919D78F61B15D14425A34142D93B24C137ED056946\nextra:\n event.trackingEnabled: "false"\n log.core.scheduler.level: info\n log.core.security.level: info\n log.level: debug\n\n')),(0,o.yg)("h2",{id:"application-history"},"Application history"),(0,o.yg)("p",null,"Endpoint to retrieve historical data about the number of total applications by timestamp."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/history/apps")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-17"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "timestamp": 1595939966153460000,\n "totalApplications": "1"\n },\n {\n "timestamp": 1595940026152892000,\n "totalApplications": "1"\n },\n {\n "timestamp": 1595940086153799000,\n "totalApplications": "2"\n },\n {\n "timestamp": 1595940146154497000,\n "totalApplications": "2"\n },\n {\n "timestamp": 1595940206155187000,\n "totalApplications": "2"\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-13"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"container-history"},"Container history"),(0,o.yg)("p",null,"Endpoint to retrieve historical data about the number of total containers by timestamp."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/history/containers")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-18"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "timestamp": 1595939966153460000,\n "totalContainers": "1"\n },\n {\n "timestamp": 1595940026152892000,\n "totalContainers": "1"\n },\n {\n "timestamp": 1595940086153799000,\n "totalContainers": "3"\n },\n {\n "timestamp": 1595940146154497000,\n "totalContainers": "3"\n },\n {\n "timestamp": 1595940206155187000,\n "totalContainers": "3"\n }\n]\n')),(0,o.yg)("h3",{id:"error-response-14"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,o.yg)("h2",{id:"endpoint-healthcheck"},"Endpoint healthcheck"),(0,o.yg)("p",null,"Endpoint to retrieve historical data about critical logs, negative resource on node/cluster/app, ..."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/healthcheck")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-19"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "Healthy": true,\n "HealthChecks": [\n {\n "Name": "Scheduling errors",\n "Succeeded": true,\n "Description": "Check for scheduling error entries in metrics",\n "DiagnosisMessage": "There were 0 scheduling errors logged in the metrics"\n },\n {\n "Name": "Failed nodes",\n "Succeeded": true,\n "Description": "Check for failed nodes entries in metrics",\n "DiagnosisMessage": "There were 0 failed nodes logged in the metrics"\n },\n {\n "Name": "Negative resources",\n "Succeeded": true,\n "Description": "Check for negative resources in the partitions",\n "DiagnosisMessage": "Partitions with negative resources: []"\n },\n {\n "Name": "Negative resources",\n "Succeeded": true,\n "Description": "Check for negative resources in the nodes",\n "DiagnosisMessage": "Nodes with negative resources: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if a node\'s allocated resource <= total resource of the node",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if total partition resource == sum of the node resources from the partition",\n "DiagnosisMessage": "Partitions with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if node total resource = allocated resource + occupied resource + available resource",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if node capacity >= allocated resources on the node",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Reservation check",\n "Succeeded": true,\n "Description": "Check the reservation nr compared to the number of nodes",\n "DiagnosisMessage": "Reservation/node nr ratio: [0.000000]"\n }\n ]\n}\n')),(0,o.yg)("h2",{id:"retrieve-full-state-dump"},"Retrieve full state dump"),(0,o.yg)("p",null,"Endpoint to retrieve the following information in a single response:"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},"Current timestamp (Unix timestamp in nanosecond)"),(0,o.yg)("li",{parentName:"ul"},"List of partitions"),(0,o.yg)("li",{parentName:"ul"},"List of applications (running, completed and rejected)"),(0,o.yg)("li",{parentName:"ul"},"Application history"),(0,o.yg)("li",{parentName:"ul"},"Nodes"),(0,o.yg)("li",{parentName:"ul"},"Generic cluster information"),(0,o.yg)("li",{parentName:"ul"},"Container history"),(0,o.yg)("li",{parentName:"ul"},"Queues"),(0,o.yg)("li",{parentName:"ul"},"RMDiagnostics"),(0,o.yg)("li",{parentName:"ul"},"Log level"),(0,o.yg)("li",{parentName:"ul"},"Configuration")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/fullstatedump")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Method")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("h3",{id:"success-response-20"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("p",null,"The output of this REST query can be rather large, and it is a combination of those which have already been demonstrated."),(0,o.yg)("p",null,"The ",(0,o.yg)("inlineCode",{parentName:"p"},"RMDiagnostics")," shows the content of the K8Shim cache. The exact content is version dependent and has not stabilised.\nThe current content shows the cached objects:"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},"nodes"),(0,o.yg)("li",{parentName:"ul"},"pods"),(0,o.yg)("li",{parentName:"ul"},"priorityClasses"),(0,o.yg)("li",{parentName:"ul"},"schedulingState (pod status)")),(0,o.yg)("h3",{id:"failure-response"},"Failure response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code"),": ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("h2",{id:"batch-events"},"Batch Events"),(0,o.yg)("p",null,"Endpoint is used to retrieve a batch of event records."),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL"),": ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/events/batch")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"METHOD")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL query parameters")," :"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("inlineCode",{parentName:"li"},"count")," (optional) : Specifies the maxmem number of events to be included in the response."),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("inlineCode",{parentName:"li"},"start")," (optional) : Specifies the starting ID for retrieving events. If the specified ID is outside the ring buffer\n(too low or too high), the response will include the lowest and highest ID values with ",(0,o.yg)("inlineCode",{parentName:"li"},"EventRecords")," being empty. ")),(0,o.yg)("h3",{id:"success-response-21"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code"),": ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{\n "InstanceUUID": "400046c6-2180-41a2-9be1-1c251ab2c498",\n "LowestID": 0,\n "HighestID": 7,\n "EventRecords": [\n {\n "type": 3,\n "objectID": "yk8s-worker",\n "message": "schedulable: true",\n "timestampNano": 1701347180239597300,\n "eventChangeType": 1,\n "eventChangeDetail": 302,\n "resource": {}\n },\n {\n "type": 3,\n "objectID": "yk8s-worker",\n "message": "Node added to the scheduler",\n "timestampNano": 1701347180239650600,\n "eventChangeType": 2,\n "resource": {\n "resources": {\n "ephemeral-storage": {\n "value": 502921060352\n },\n "hugepages-1Gi": {},\n "hugepages-2Mi": {},\n "memory": {\n "value": 33424998400\n },\n "pods": {\n "value": 110\n },\n "vcore": {\n "value": 8000\n }\n }\n }\n }\n ]\n}\n')),(0,o.yg)("h3",{id:"error-response-15"},"Error response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,o.yg)("h3",{id:"event-stream"},"Event stream"),(0,o.yg)("p",null,"Creates a persistent HTTP connection for event streaming. New events are sent to the clients immediately, so unlike the batch interface, there is no need for polling.\nThe number of active connections is limited. The default setting is 100 connections total and 15 connections per host. The respective configmap properties are ",(0,o.yg)("inlineCode",{parentName:"p"},"event.maxStreams")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"event.maxStreamsPerHost"),". "),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL"),": ",(0,o.yg)("inlineCode",{parentName:"p"},"/ws/v1/events/stream")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"METHOD")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"GET")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"URL query parameters"),":"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("inlineCode",{parentName:"li"},"count")," (optional) : Specifies the number of past events (those which have been generated before the connection establishment) to include in the response. Default value is 0.")),(0,o.yg)("h3",{id:"success-response-22"},"Success response"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code"),": ",(0,o.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Content examples")),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-json"},'{"type":2,"objectID":"app-1","timestampNano":1708465452903045265,"eventChangeType":1,"eventChangeDetail":204,"resource":{}}\n{"type":2,"objectID":"app-1","timestampNano":1708465452903192898,"eventChangeType":2,"eventChangeDetail":201,"referenceID":"alloc-1","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n{"type":3,"objectID":"node-1:1234","timestampNano":1708465452903312146,"eventChangeType":2,"eventChangeDetail":303,"referenceID":"alloc-1","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n{"type":2,"objectID":"app-1","timestampNano":1708465452903474210,"eventChangeType":1,"eventChangeDetail":205,"resource":{}}\n{"type":5,"objectID":"testuser","timestampNano":1708465452903506166,"eventChangeType":2,"eventChangeDetail":603,"referenceID":"root.singleleaf","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n')),(0,o.yg)("h3",{id:"error-responses"},"Error responses"),(0,o.yg)("p",null,(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"400 Bad Request")," (URL query is invalid)\n",(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"503 Service Unavailable")," (Too many active streaming connections)\n",(0,o.yg)("strong",{parentName:"p"},"Code")," : ",(0,o.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6bf8e8e6.b58022a8.js b/assets/js/6bf8e8e6.b58022a8.js deleted file mode 100644 index d27a6c5c260..00000000000 --- a/assets/js/6bf8e8e6.b58022a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[13843],{58860:(e,n,a)=>{a.d(n,{xA:()=>u,yg:()=>m});var r=a(37953);function t(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function o(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,r)}return a}function s(e){for(var n=1;n=0||(t[a]=e[a]);return t}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(t[a]=e[a])}return t}var l=r.createContext({}),p=function(e){var n=r.useContext(l),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},u=function(e){var n=p(e.components);return r.createElement(l.Provider,{value:n},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var a=e.components,t=e.mdxType,o=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),c=p(a),d=t,m=c["".concat(l,".").concat(d)]||c[d]||g[d]||o;return a?r.createElement(m,s(s({ref:n},u),{},{components:a})):r.createElement(m,s({ref:n},u))}));function m(e,n){var a=arguments,t=n&&n.mdxType;if("string"==typeof e||t){var o=a.length,s=new Array(o);s[0]=d;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i[c]="string"==typeof e?e:t,s[1]=i;for(var p=2;p{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=a(72994),t=(a(37953),a(58860));const o={id:"scheduler",title:"Scheduler"},s=void 0,i={unversionedId:"api/scheduler",id:"api/scheduler",title:"Scheduler",description:"\x3c!--",source:"@site/docs/api/scheduler.md",sourceDirName:"api",slug:"/api/scheduler",permalink:"/docs/next/api/scheduler",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler",title:"Scheduler"},sidebar:"docs",previous:{title:"Cluster",permalink:"/docs/next/api/cluster"},next:{title:"System",permalink:"/docs/next/api/system"}},l={},p=[{value:"Partitions",id:"partitions",level:2},{value:"Success response",id:"success-response",level:3},{value:"Error response",id:"error-response",level:3},{value:"Queues",id:"queues",level:2},{value:"Partition queues",id:"partition-queues",level:3},{value:"Success response",id:"success-response-1",level:3},{value:"Error response",id:"error-response-1",level:3},{value:"Applications",id:"applications",level:2},{value:"Partition applications",id:"partition-applications",level:3},{value:"Success response",id:"success-response-2",level:3},{value:"Queue applications",id:"queue-applications",level:3},{value:"Success response",id:"success-response-3",level:3},{value:"Error response",id:"error-response-2",level:3},{value:"Application",id:"application",level:2},{value:"Partition/Queue application",id:"partitionqueue-application",level:3},{value:"Success response",id:"success-response-4",level:3},{value:"Error response",id:"error-response-3",level:3},{value:"UsersTracker",id:"userstracker",level:2},{value:"Get users usage tracking information",id:"get-users-usage-tracking-information",level:3},{value:"Success response",id:"success-response-5",level:3},{value:"Error response",id:"error-response-4",level:3},{value:"UserTracker",id:"usertracker",level:2},{value:"Get specific user usage tracking information",id:"get-specific-user-usage-tracking-information",level:3},{value:"Success response",id:"success-response-6",level:3},{value:"Error response",id:"error-response-5",level:3},{value:"GroupsTracker",id:"groupstracker",level:2},{value:"Get groups usage tracking information",id:"get-groups-usage-tracking-information",level:3},{value:"Success response",id:"success-response-7",level:3},{value:"Error response",id:"error-response-6",level:3},{value:"GroupTracker",id:"grouptracker",level:2},{value:"Get specific group usage tracking information",id:"get-specific-group-usage-tracking-information",level:3},{value:"Success response",id:"success-response-8",level:3},{value:"Error response",id:"error-response-7",level:3},{value:"Nodes",id:"nodes",level:2},{value:"Partition nodes",id:"partition-nodes",level:3},{value:"Success response",id:"success-response-9",level:3},{value:"Error response",id:"error-response-8",level:3},{value:"Node",id:"node",level:2},{value:"Partition node",id:"partition-node",level:3},{value:"Success response",id:"success-response-10",level:3},{value:"Error response",id:"error-response-9",level:3},{value:"Node utilization",id:"node-utilization",level:2},{value:"Success response",id:"success-response-11",level:3},{value:"Error response",id:"error-response-10",level:3},{value:"Node utilizations",id:"node-utilizations",level:2},{value:"Success response",id:"success-response-12",level:3},{value:"Error response",id:"error-response-11",level:3},{value:"Goroutines info",id:"goroutines-info",level:2},{value:"Success response",id:"success-response-13",level:3},{value:"Error response",id:"error-response-12",level:3},{value:"Metrics",id:"metrics",level:2},{value:"Success response",id:"success-response-14",level:3},{value:"Configuration validation",id:"configuration-validation",level:2},{value:"Success response",id:"success-response-15",level:3},{value:"Allowed configuration",id:"allowed-configuration",level:4},{value:"Disallowed configuration",id:"disallowed-configuration",level:4},{value:"Configuration",id:"configuration",level:2},{value:"Success response",id:"success-response-16",level:3},{value:"Application history",id:"application-history",level:2},{value:"Success response",id:"success-response-17",level:3},{value:"Error response",id:"error-response-13",level:3},{value:"Container history",id:"container-history",level:2},{value:"Success response",id:"success-response-18",level:3},{value:"Error response",id:"error-response-14",level:3},{value:"Endpoint healthcheck",id:"endpoint-healthcheck",level:2},{value:"Success response",id:"success-response-19",level:3},{value:"Retrieve full state dump",id:"retrieve-full-state-dump",level:2},{value:"Success response",id:"success-response-20",level:3},{value:"Failure response",id:"failure-response",level:3},{value:"Batch Events",id:"batch-events",level:2},{value:"Success response",id:"success-response-21",level:3},{value:"Error response",id:"error-response-15",level:3},{value:"Event stream",id:"event-stream",level:3},{value:"Success response",id:"success-response-22",level:3},{value:"Error responses",id:"error-responses",level:3}],u={toc:p},c="wrapper";function g(e){let{components:n,...a}=e;return(0,t.yg)(c,(0,r.A)({},u,a,{components:n,mdxType:"MDXLayout"}),(0,t.yg)("h1",{id:"overview"},"Overview"),(0,t.yg)("p",null,"The scheduler REST API returns information about various objects used by the YuniKorn Scheduler."),(0,t.yg)("p",null,"Many of these APIs return collections of resources. Internally, all resources are represented as raw\n64-bit signed integer types. When interpreting responses from the REST API, resources of type ",(0,t.yg)("inlineCode",{parentName:"p"},"memory"),"\nare returned in units of bytes while resources of type ",(0,t.yg)("inlineCode",{parentName:"p"},"vcore")," are returned in units of millicores\n(thousands of a core). All other resource types have no specific unit assigned."),(0,t.yg)("p",null,"Under the ",(0,t.yg)("inlineCode",{parentName:"p"},"allocations")," field in the response content for the app/node-related calls in the following spec, ",(0,t.yg)("inlineCode",{parentName:"p"},"placeholderUsed")," refers to whether or not the allocation is a replacement for a placeholder. If true, ",(0,t.yg)("inlineCode",{parentName:"p"},"requestTime")," is the creation time of its placeholder allocation, otherwise it's that of the allocation's ask. ",(0,t.yg)("inlineCode",{parentName:"p"},"allocationTime")," is the creation time of the allocation, and ",(0,t.yg)("inlineCode",{parentName:"p"},"allocationDelay")," is simply the difference between ",(0,t.yg)("inlineCode",{parentName:"p"},"allocationTime")," and ",(0,t.yg)("inlineCode",{parentName:"p"},"requestTime"),"."),(0,t.yg)("h2",{id:"partitions"},"Partitions"),(0,t.yg)("p",null,"Returns general information and statistics about a partition."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partitions")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "clusterId": "mycluster",\n "name": "default",\n "state": "Active",\n "lastStateTransitionTime": 1649167576110754000,\n "capacity": {\n "capacity": {\n "ephemeral-storage": 188176871424,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 1000000000,\n "pods": 330,\n "vcore": 1000\n },\n "usedCapacity": {\n "memory": 800000000,\n "vcore": 500\n },\n "utilization": {\n "memory": 80,\n "vcore": 50\n }\n },\n "nodeSortingPolicy": {\n "type": "fair",\n "resourceWeights": {\n "memory": 1.5,\n "vcore": 1.3\n }\n },\n "applications": {\n "New": 5,\n "Pending": 5,\n "total": 10\n },\n "totalContainers": 0,\n "totalNodes": 2\n },\n {\n "clusterId": "mycluster",\n "name": "gpu",\n "state": "Active",\n "lastStateTransitionTime": 1649167576111236000,\n "capacity": {\n "capacity": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "usedCapacity": {\n "memory": 500000000,\n "vcore": 300\n },\n "utilization": {\n "memory": 25,\n "vcore": 15\n }\n },\n "nodeSortingPolicy": {\n "type": "binpacking",\n "resourceWeights": {\n "memory": 0,\n "vcore": 4.11\n }\n },\n "applications": {\n "New": 5,\n "Running": 10,\n "Pending": 5,\n "total": 20\n },\n "totalContainers": 20,\n "totalNodes": 5\n }\n]\n')),(0,t.yg)("h3",{id:"error-response"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"queues"},"Queues"),(0,t.yg)("h3",{id:"partition-queues"},"Partition queues"),(0,t.yg)("p",null,"Fetch all Queues associated with given Partition and displays general information about the queues like name, status, capacities and properties.\nThe queues' hierarchy is kept in the response json. "),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queues")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-1"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("p",null,"For the default queue hierarchy (only ",(0,t.yg)("inlineCode",{parentName:"p"},"root.default")," leaf queue exists) a similar response to the following is sent back to the client:"),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "queuename": "root",\n "status": "Active",\n "maxResource": {\n "ephemeral-storage": 188176871424,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 8000000000,\n "pods": 330,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "allocatedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "pendingResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "isLeaf": "false",\n "isManaged": "false",\n "properties": {\n "application.sort.policy": "stateaware"\n },\n "parent": "",\n "template": {\n "maxResource": {\n "memory": 8000000000,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "properties": {\n "application.sort.policy": "stateaware"\n }\n },\n "partition": "default",\n "children": [\n {\n "queuename": "root.default",\n "status": "Active",\n "maxResource": {\n "memory": 8000000000,\n "vcore": 8000\n },\n "guaranteedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "allocatedResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "pendingResource": {\n "memory": 54000000,\n "vcore": 80\n },\n "isLeaf": "true",\n "isManaged": "false",\n "properties": {\n "application.sort.policy": "stateaware"\n },\n "parent": "root",\n "template": null,\n "children": [],\n "absUsedCapacity": {\n "memory": 1,\n "vcore": 0\n },\n "maxRunningApps": 12,\n "runningApps": 4,\n "allocatingAcceptedApps": [\n "app-1",\n "app-2"\n ]\n }\n ],\n "absUsedCapacity": {\n "memory": 1,\n "vcore": 0\n }\n } \n]\n')),(0,t.yg)("h3",{id:"error-response-1"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"applications"},"Applications"),(0,t.yg)("h3",{id:"partition-applications"},"Partition applications"),(0,t.yg)("p",null,"Fetch all Applications for the given Partition/State combination and displays general information about the applications like used resources, queue name, submission time and allocations.\nOnly following application states are allowed: active, rejected, completed. Active is a fake state that represents all application states except completed and rejected.\nFor active state, can narrow the result by status query parameters(case-insensitive). For example, can fetch ",(0,t.yg)("inlineCode",{parentName:"p"},"Running")," applications for the default partition by\n",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/default/applications/active?status=running"),"."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/:partition/applications/:state")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-2"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("p",null,"The content of the application object is the same as Queue Applications. See\n",(0,t.yg)("a",{parentName:"p",href:"#queue-applications"},"Queue Applications")," for details."),(0,t.yg)("h3",{id:"queue-applications"},"Queue applications"),(0,t.yg)("p",null,"Fetch all Applications for the given Partition/Queue combination and displays general information about the applications like used resources, queue name, submission time and allocations."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queue/{queueName}/applications")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-3"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Deprecated"),":"),(0,t.yg)("p",null,"Field ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid")," has been deprecated, would be removed from below response in YUNIKORN 1.7.0 release. ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," has replaced ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid"),". Both ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid")," and ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," fields have the same value. ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," has extra suffix containing hyphen and counter (-0, -1 and so on) at the end. "),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("p",null,"In the example below there are three allocations belonging to two applications, one with a pending request."),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "applicationID": "application-0001",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [\n {\n "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task2"\n },\n "requestTime": 16487540320812345678,\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingCount": 1,\n "priority": "0",\n "requiredNodeId": "",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderTimeout": 0,\n "taskGroupName": "",\n "allocationLog": [\n {\n "message": "node(s) didn\'t match Pod\'s node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate",\n "lastOccurrence": 16487540320812346001,\n "count": 81\n },\n {\n "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate, node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346002,\n "count": 504\n },\n {\n "message": "node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346003,\n "count": 1170\n }\n ]\n }\n ],\n "allocations": [\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": true\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409145509400,\n "applicationState": "Starting"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [\n {\n "taskGroupName": "task-group-example",\n "count": 2,\n "minResource": {\n "memory": 1000000000,\n "vcore": 100\n },\n "replaced": 1,\n "timedout": 1\n }\n ],\n "hasReserved": false,\n "reservations": []\n },\n {\n "applicationID": "application-0002",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [],\n "allocations": [\n {\n "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID": "08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n },\n {\n "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task1"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b",\n "allocationID": "96beeb45-5ed2-4c19-9a83-2ac807637b3b-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0002",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409145509400,\n "applicationState": "Starting"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [],\n "hasReserved": false,\n "reservations": []\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-2"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"application"},"Application"),(0,t.yg)("h3",{id:"partitionqueue-application"},"Partition/Queue application"),(0,t.yg)("p",null,"Fetch an Application given a Partition, Queue(optional) and Application ID and displays general information about the application like used resources, queue name, submission time and allocations."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/application/{appId}")," or ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/queue/{queueName}/application/{appId}")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-4"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Deprecated"),":"),(0,t.yg)("p",null,"Field ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid")," has been deprecated, would be removed from below response in YUNIKORN 1.7.0 release. ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," has replaced ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid"),". Both ",(0,t.yg)("inlineCode",{parentName:"p"},"uuid")," and ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," fields have the same value. ",(0,t.yg)("inlineCode",{parentName:"p"},"AllocationID")," has extra suffix containing hyphen and counter (-0, -1 and so on) at the end."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "applicationID": "application-0001",\n "usedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "maxUsedResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingResource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "partition": "default",\n "queueName": "root.default",\n "submissionTime": 1648754032076020293,\n "requests": [\n {\n "allocationKey": "f137fab6-3cfa-4536-93f7-bfff92689382",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task2"\n },\n "requestTime": 16487540320812345678,\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "pendingCount": 1,\n "priority": "0",\n "requiredNodeId": "",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderTimeout": 0,\n "taskGroupName": "",\n "allocationLog": [\n {\n "message": "node(s) didn\'t match Pod\'s node affinity, node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate",\n "lastOccurrence": 16487540320812346001,\n "count": 81\n },\n {\n "message": "node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn\'t tolerate, node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346002,\n "count": 504\n },\n {\n "message": "node(s) didn\'t match Pod\'s node affinity",\n "lastOccurrence": 16487540320812346003,\n "count": 1170\n }\n ]\n }\n ],\n "allocations": [\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": true\n }\n ],\n "applicationState": "Running",\n "user": "system:serviceaccount:kube-system:deployment-controller",\n "groups": [\n "system:serviceaccounts",\n "system:serviceaccounts:kube-system",\n "system:authenticated"\n ],\n "rejectedMessage": "",\n "stateLog": [\n {\n "time": 1648741409145224000,\n "applicationState": "Accepted"\n },\n {\n "time": 1648741409145509400,\n "applicationState": "Starting"\n },\n {\n "time": 1648741409147432100,\n "applicationState": "Running"\n }\n ],\n "placeholderData": [\n {\n "taskGroupName": "task-group-example",\n "count": 2,\n "minResource": {\n "memory": 1000000000,\n "vcore": 100\n },\n "replaced": 1,\n "timedout": 1\n }\n ],\n "hasReserved": false,\n "reservations": []\n}\n')),(0,t.yg)("h3",{id:"error-response-3"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"userstracker"},"UsersTracker"),(0,t.yg)("h3",{id:"get-users-usage-tracking-information"},"Get users usage tracking information"),(0,t.yg)("p",null,"Fetch all users usage given a Partition and displays general information about the users managed by YuniKorn."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/users")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-5"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "userName": "user1",\n "groups": {\n "app2": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n },\n {\n "userName": "user2",\n "groups": {\n "app1": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 11000000000,\n "vcore": 10000\n },\n "runningApplications": ["app1", "app2", "app3"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 5000000000,\n "vcore": 5000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "runningApplications": [\n "app3"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-4"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"usertracker"},"UserTracker"),(0,t.yg)("h3",{id:"get-specific-user-usage-tracking-information"},"Get specific user usage tracking information"),(0,t.yg)("p",null,"Fetch specific user usage given a Partition and displays general information about the users managed by YuniKorn."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/user/{userName}")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-6"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "userName": "user1",\n "groups": {\n "app1": "tester"\n },\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n}\n')),(0,t.yg)("h3",{id:"error-response-5"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"groupstracker"},"GroupsTracker"),(0,t.yg)("h3",{id:"get-groups-usage-tracking-information"},"Get groups usage tracking information"),(0,t.yg)("p",null,"Fetch all groups usage given a Partition and displays general information about the groups managed by YuniKorn."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/groups")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-7"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "groupName": "group1",\n "applications": ["app1", "app2"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n },\n {\n "groupName": "group2",\n "applications": ["app1", "app2", "app3"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 11000000000,\n "vcore": 10000\n },\n "runningApplications": ["app1", "app2", "app3"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 5000000000,\n "vcore": 5000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "runningApplications": [\n "app3"\n ],\n "children": []\n }]\n }\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-6"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"grouptracker"},"GroupTracker"),(0,t.yg)("h3",{id:"get-specific-group-usage-tracking-information"},"Get specific group usage tracking information"),(0,t.yg)("p",null,"Fetch specific group usage given a Partition and displays general information about the groups managed by YuniKorn."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/usage/group/{groupName}")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-8"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "groupName": "group1",\n "applications": ["app1", "app2"],\n "queues":\n {\n "queuePath": "root",\n "resourceUsage": {\n "memory": 12000000000,\n "vcore": 12000\n },\n "runningApplications": ["app1", "app2"],\n "children": [\n {\n "queuePath": "root.default",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": ["app1"],\n "children": []\n },\n {\n "queuePath": "root.test",\n "resourceUsage": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "runningApplications": [\n "app2"\n ],\n "children": []\n }]\n }\n}\n')),(0,t.yg)("h3",{id:"error-response-7"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"nodes"},"Nodes"),(0,t.yg)("h3",{id:"partition-nodes"},"Partition nodes"),(0,t.yg)("p",null,"Fetch all Nodes associated with given Partition and displays general information about the nodes managed by YuniKorn.\nNode details include host and rack name, capacity, resources, utilization, and allocations."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/nodes")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-9"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("p",null,"Here you can see an example response from a 2-node cluster having 3 allocations."),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "nodeID": "node-0001",\n "hostName": "",\n "rackName": "",\n "attributes": {\n "beta.kubernetes.io/arch": "amd64",\n "beta.kubernetes.io/os": "linux",\n "kubernetes.io/arch": "amd64",\n "kubernetes.io/hostname": "node-0001",\n "kubernetes.io/os": "linux",\n "node-role.kubernetes.io/control-plane": "",\n "node-role.kubernetes.io/master": "",\n "node.kubernetes.io/exclude-from-external-load-balancers": "",\n "ready": "true",\n "si.io/hostname": "node-0001",\n "si.io/rackname": "/rack-default",\n "si/instance-type": "",\n "si/node-partition": "[mycluster]default"\n },\n "capacity": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 14577000000,\n "pods": 110,\n "vcore": 10000\n },\n "allocated": {\n "memory": 6000000000,\n "vcore": 6000\n },\n "occupied": {\n "memory": 154000000,\n "vcore" :750\n },\n "available": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 6423000000,\n "pods": 110,\n "vcore": 1250\n },\n "utilized": {\n "memory": 3,\n "vcore": 13\n },\n "allocations": [\n {\n "allocationKey": "54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID": "08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n },\n {\n "allocationKey": "deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0002",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task0"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID": "9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource": {\n "memory": 4000000000,\n "vcore": 4000\n },\n "priority": "0",\n "nodeId": "node-0001",\n "applicationId": "application-0002",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "schedulable": true\n },\n {\n "nodeID": "node-0002",\n "hostName": "",\n "rackName": "",\n "attributes": {\n "beta.kubernetes.io/arch": "amd64",\n "beta.kubernetes.io/os": "linux",\n "kubernetes.io/arch": "amd64",\n "kubernetes.io/hostname": "node-0002",\n "kubernetes.io/os": "linux",\n "ready": "false",\n "si.io/hostname": "node-0002",\n "si.io/rackname": "/rack-default",\n "si/instance-type": "",\n "si/node-partition": "[mycluster]default"\n },\n "capacity": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 14577000000,\n "pods": 110,\n "vcore": 10000\n },\n "allocated": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "occupied": {\n "memory": 154000000,\n "vcore" :750\n },\n "available": {\n "ephemeral-storage": 75850798569,\n "hugepages-1Gi": 0,\n "hugepages-2Mi": 0,\n "memory": 6423000000,\n "pods": 110,\n "vcore": 1250\n },\n "utilized": {\n "memory": 8,\n "vcore": 38\n },\n "allocations": [\n {\n "allocationKey": "af3bd2f3-31c5-42dd-8f3f-c2298ebdec81",\n "allocationTags": {\n "kubernetes.io/label/app": "sleep",\n "kubernetes.io/label/applicationId": "application-0001",\n "kubernetes.io/label/queue": "root.default",\n "kubernetes.io/meta/namespace": "default",\n "kubernetes.io/meta/podName": "task1"\n },\n "requestTime": 1648754034098912461,\n "allocationTime": 1648754035973982920,\n "allocationDelay": 1875070459,\n "uuid": "96beeb45-5ed2-4c19-9a83-2ac807637b3b",\n "allocationID": "96beeb45-5ed2-4c19-9a83-2ac807637b3b-0",\n "resource": {\n "memory": 2000000000,\n "vcore": 2000\n },\n "priority": "0",\n "nodeId": "node-0002",\n "applicationId": "application-0001",\n "partition": "default",\n "placeholder": false,\n "placeholderUsed": false\n }\n ],\n "schedulable": true,\n "isReserved": false,\n "reservations": []\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-8"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"node"},"Node"),(0,t.yg)("h3",{id:"partition-node"},"Partition node"),(0,t.yg)("p",null,"Fetch a Node associated with given Partition and Node ID and displays general information about the node managed by YuniKorn.\nNode details include host and rack name, capacity, resources, utilization, and allocations."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/partition/{partitionName}/node/{nodeId}")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-10"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "nodeID":"node-0001",\n "hostName":"",\n "rackName":"",\n "capacity":{\n "ephemeral-storage":75850798569,\n "hugepages-1Gi":0,\n "hugepages-2Mi":0,\n "memory":14577000000,\n "pods":110,\n "vcore":10000\n },\n "allocated":{\n "memory":6000000000,\n "vcore":6000\n },\n "occupied":{\n "memory":154000000,\n "vcore":750\n },\n "available":{\n "ephemeral-storage":75850798569,\n "hugepages-1Gi":0,\n "hugepages-2Mi":0,\n "memory":6423000000,\n "pods":110,\n "vcore":1250\n },\n "utilized":{\n "memory":3,\n "vcore":13\n },\n "allocations":[\n {\n "allocationKey":"54e5d77b-f4c3-4607-8038-03c9499dd99d",\n "allocationTags":{\n "kubernetes.io/label/app":"sleep",\n "kubernetes.io/label/applicationId":"application-0001",\n "kubernetes.io/label/queue":"root.default",\n "kubernetes.io/meta/namespace":"default",\n "kubernetes.io/meta/podName":"task0"\n },\n "requestTime":1648754034098912461,\n "allocationTime":1648754035973982920,\n "allocationDelay":1875070459,\n "uuid":"08033f9a-4699-403c-9204-6333856b41bd",\n "allocationID":"08033f9a-4699-403c-9204-6333856b41bd-0",\n "resource":{\n "memory":2000000000,\n "vcore":2000\n },\n "priority":"0",\n "nodeId":"node-0001",\n "applicationId":"application-0001",\n "partition":"default",\n "placeholder":false,\n "placeholderUsed":false\n },\n {\n "allocationKey":"deb12221-6b56-4fe9-87db-ebfadce9aa20",\n "allocationTags":{\n "kubernetes.io/label/app":"sleep",\n "kubernetes.io/label/applicationId":"application-0002",\n "kubernetes.io/label/queue":"root.default",\n "kubernetes.io/meta/namespace":"default",\n "kubernetes.io/meta/podName":"task0"\n },\n "requestTime":1648754034098912461,\n "allocationTime":1648754035973982920,\n "allocationDelay":1875070459,\n "uuid":"9af35d44-2d6f-40d1-b51d-758859e6b8a8",\n "allocationID":"9af35d44-2d6f-40d1-b51d-758859e6b8a8-0",\n "resource":{\n "memory":4000000000,\n "vcore":4000\n },\n "priority":"0",\n "nodeId":"node-0001",\n "applicationId":"application-0002",\n "partition":"default",\n "placeholder":false,\n "placeholderUsed":false\n }\n ],\n "schedulable":true\n}\n')),(0,t.yg)("h3",{id:"error-response-9"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"node-utilization"},"Node utilization"),(0,t.yg)("p",null,"Show how every node is distributed with regard to dominant resource utilization."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Status")," : Deprecated since v1.5.0 and will be removed in the next major release. Replaced with ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilizations"),"."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilization")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-11"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "type": "vcore",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 1,\n "nodeNames": [\n "aethergpu"\n ]\n },\n {\n "bucketName": "10-20%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n ... \n ]\n}\n')),(0,t.yg)("h3",{id:"error-response-10"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"node-utilizations"},"Node utilizations"),(0,t.yg)("p",null,"Show the nodes utilization of different types of resources in a cluster."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/node-utilizations")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-12"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "clusterId": "mycluster",\n "partition": "default",\n "utilizations": [\n {\n "type": "pods",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n {\n "bucketName": "10-20%"\n },\n ...\n ]\n },\n {\n "type": "vcores",\n "utilization": [\n {\n "bucketName": "0-10%",\n "numOfNodes": 2,\n "nodeNames": [\n "primary-node",\n "second-node"\n ]\n },\n {\n "bucketName": "10-20%"\n },\n ...\n ]\n },\n ...\n ]\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-11"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"goroutines-info"},"Goroutines info"),(0,t.yg)("p",null,"Dumps the stack traces of the currently running goroutines."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/stack")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-13"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-text"},"goroutine 356 [running\n]:\ngithub.com/apache/yunikorn-core/pkg/webservice.getStackInfo.func1(0x30a0060,\n0xc003e900e0,\n0x2)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 41 +0xab\ngithub.com/apache/yunikorn-core/pkg/webservice.getStackInfo(0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/handlers.go: 48 +0x71\nnet/http.HandlerFunc.ServeHTTP(0x2df0e10,\n0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /usr/local/go/src/net/http/server.go: 1995 +0x52\ngithub.com/apache/yunikorn-core/pkg/webservice.Logger.func1(0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /yunikorn/go/pkg/mod/github.com/apache/yunikorn-core@v0.0.0-20200717041747-f3e1c760c714/pkg/webservice/webservice.go: 65 +0xd4\nnet/http.HandlerFunc.ServeHTTP(0xc00003a570,\n0x30a0060,\n0xc003e900e0,\n0xc00029ba00)\n /usr/local/go/src/net/http/server.go: 1995 +0x52\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc00029cb40,\n0x30a0060,\n0xc003e900e0,\n0xc0063fee00)\n /yunikorn/go/pkg/mod/github.com/gorilla/mux@v1.7.3/mux.go: 212 +0x140\nnet/http.serverHandler.ServeHTTP(0xc0000df520,\n0x30a0060,\n0xc003e900e0,\n0xc0063fee00)\n /usr/local/go/src/net/http/server.go: 2774 +0xcf\nnet/http.(*conn).serve(0xc0000eab40,\n0x30a61a0,\n0xc003b74000)\n /usr/local/go/src/net/http/server.go: 1878 +0x812\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go: 2884 +0x4c5\n\ngoroutine 1 [chan receive,\n 26 minutes\n]:\nmain.main()\n /yunikorn/pkg/shim/main.go: 52 +0x67a\n\ngoroutine 19 [syscall,\n 26 minutes\n]:\nos/signal.signal_recv(0x1096f91)\n /usr/local/go/src/runtime/sigqueue.go: 139 +0x9f\nos/signal.loop()\n /usr/local/go/src/os/signal/signal_unix.go: 23 +0x30\ncreated by os/signal.init.0\n /usr/local/go/src/os/signal/signal_unix.go: 29 +0x4f\n\n...\n")),(0,t.yg)("h3",{id:"error-response-12"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"metrics"},"Metrics"),(0,t.yg)("p",null,"Endpoint to retrieve metrics from the Prometheus server.\nThe metrics are dumped with help messages and type information."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/metrics")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-14"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-text"},'# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n# TYPE go_gc_duration_seconds summary\ngo_gc_duration_seconds{quantile="0"} 2.567e-05\ngo_gc_duration_seconds{quantile="0.25"} 3.5727e-05\ngo_gc_duration_seconds{quantile="0.5"} 4.5144e-05\ngo_gc_duration_seconds{quantile="0.75"} 6.0024e-05\ngo_gc_duration_seconds{quantile="1"} 0.00022528\ngo_gc_duration_seconds_sum 0.021561648\ngo_gc_duration_seconds_count 436\n# HELP go_goroutines Number of goroutines that currently exist.\n# TYPE go_goroutines gauge\ngo_goroutines 82\n# HELP go_info Information about the Go environment.\n# TYPE go_info gauge\ngo_info{version="go1.12.17"} 1\n# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.\n# TYPE go_memstats_alloc_bytes gauge\ngo_memstats_alloc_bytes 9.6866248e+07\n\n...\n\n# HELP yunikorn_scheduler_vcore_nodes_usage Nodes resource usage, by resource name.\n# TYPE yunikorn_scheduler_vcore_nodes_usage gauge\nyunikorn_scheduler_vcore_nodes_usage{range="(10%, 20%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(20%,30%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(30%,40%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(40%,50%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(50%,60%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(60%,70%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(70%,80%]"} 1\nyunikorn_scheduler_vcore_nodes_usage{range="(80%,90%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="(90%,100%]"} 0\nyunikorn_scheduler_vcore_nodes_usage{range="[0,10%]"} 0\n')),(0,t.yg)("h2",{id:"configuration-validation"},"Configuration validation"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/validate-conf")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"POST")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-15"},"Success response"),(0,t.yg)("p",null,"Regardless whether the configuration is allowed or not if the server was able to process the request, it will yield a 200 HTTP status code."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("h4",{id:"allowed-configuration"},"Allowed configuration"),(0,t.yg)("p",null,"Sending the following simple configuration yields an accept"),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: test\n")),(0,t.yg)("p",null,"Reponse"),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "allowed": true,\n "reason": ""\n}\n')),(0,t.yg)("h4",{id:"disallowed-configuration"},"Disallowed configuration"),(0,t.yg)("p",null,'The following configuration is not allowed due to the "wrong_text" field put into the yaml file.'),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: test\n - wrong_text\n")),(0,t.yg)("p",null,"Reponse"),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "allowed": false,\n "reason": "yaml: unmarshal errors:\\n line 7: cannot unmarshal !!str `wrong_text` into configs.PartitionConfig"\n}\n')),(0,t.yg)("h2",{id:"configuration"},"Configuration"),(0,t.yg)("p",null,"Endpoint to retrieve the current scheduler configuration"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/config")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-16"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example (with ",(0,t.yg)("inlineCode",{parentName:"strong"},"Accept: application/json")," header)")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "Partitions": [\n {\n "Name": "default",\n "Queues": [\n {\n "Name": "root",\n "Parent": true,\n "Resources": {},\n "SubmitACL": "*",\n "ChildTemplate": {\n "Resources": {}\n }\n }\n ],\n "PlacementRules": [\n {\n "Name": "tag",\n "Create": true,\n "Filter": {\n "Type": ""\n },\n "Value": "namespace"\n }\n ],\n "Preemption": {\n "Enabled": false\n },\n "NodeSortPolicy": {\n "Type": ""\n }\n }\n ],\n "Checksum": "FD5D3726DF0F02416E02F3919D78F61B15D14425A34142D93B24C137ED056946",\n "Extra": {\n "event.trackingEnabled": "false",\n "log.core.scheduler.level": "info",\n "log.core.security.level": "info",\n "log.level": "debug"\n }\n}\n')),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content example (without ",(0,t.yg)("inlineCode",{parentName:"strong"},"Accept: application/json")," header)")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-yaml"},'partitions:\n - name: default\n queues:\n - name: root\n parent: true\n submitacl: "*"\n placementrules:\n - name: tag\n create: true\n value: namespace\nchecksum: FD5D3726DF0F02416E02F3919D78F61B15D14425A34142D93B24C137ED056946\nextra:\n event.trackingEnabled: "false"\n log.core.scheduler.level: info\n log.core.security.level: info\n log.level: debug\n\n')),(0,t.yg)("h2",{id:"application-history"},"Application history"),(0,t.yg)("p",null,"Endpoint to retrieve historical data about the number of total applications by timestamp."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/history/apps")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-17"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "timestamp": 1595939966153460000,\n "totalApplications": "1"\n },\n {\n "timestamp": 1595940026152892000,\n "totalApplications": "1"\n },\n {\n "timestamp": 1595940086153799000,\n "totalApplications": "2"\n },\n {\n "timestamp": 1595940146154497000,\n "totalApplications": "2"\n },\n {\n "timestamp": 1595940206155187000,\n "totalApplications": "2"\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-13"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"container-history"},"Container history"),(0,t.yg)("p",null,"Endpoint to retrieve historical data about the number of total containers by timestamp."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/history/containers")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-18"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'[\n {\n "timestamp": 1595939966153460000,\n "totalContainers": "1"\n },\n {\n "timestamp": 1595940026152892000,\n "totalContainers": "1"\n },\n {\n "timestamp": 1595940086153799000,\n "totalContainers": "3"\n },\n {\n "timestamp": 1595940146154497000,\n "totalContainers": "3"\n },\n {\n "timestamp": 1595940206155187000,\n "totalContainers": "3"\n }\n]\n')),(0,t.yg)("h3",{id:"error-response-14"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "status_code": 500,\n "message": "system error message. for example, json: invalid UTF-8 in string: ..",\n "description": "system error message. for example, json: invalid UTF-8 in string: .."\n}\n')),(0,t.yg)("h2",{id:"endpoint-healthcheck"},"Endpoint healthcheck"),(0,t.yg)("p",null,"Endpoint to retrieve historical data about critical logs, negative resource on node/cluster/app, ..."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/scheduler/healthcheck")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-19"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "Healthy": true,\n "HealthChecks": [\n {\n "Name": "Scheduling errors",\n "Succeeded": true,\n "Description": "Check for scheduling error entries in metrics",\n "DiagnosisMessage": "There were 0 scheduling errors logged in the metrics"\n },\n {\n "Name": "Failed nodes",\n "Succeeded": true,\n "Description": "Check for failed nodes entries in metrics",\n "DiagnosisMessage": "There were 0 failed nodes logged in the metrics"\n },\n {\n "Name": "Negative resources",\n "Succeeded": true,\n "Description": "Check for negative resources in the partitions",\n "DiagnosisMessage": "Partitions with negative resources: []"\n },\n {\n "Name": "Negative resources",\n "Succeeded": true,\n "Description": "Check for negative resources in the nodes",\n "DiagnosisMessage": "Nodes with negative resources: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if a node\'s allocated resource <= total resource of the node",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if total partition resource == sum of the node resources from the partition",\n "DiagnosisMessage": "Partitions with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if node total resource = allocated resource + occupied resource + available resource",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Consistency of data",\n "Succeeded": true,\n "Description": "Check if node capacity >= allocated resources on the node",\n "DiagnosisMessage": "Nodes with inconsistent data: []"\n },\n {\n "Name": "Reservation check",\n "Succeeded": true,\n "Description": "Check the reservation nr compared to the number of nodes",\n "DiagnosisMessage": "Reservation/node nr ratio: [0.000000]"\n }\n ]\n}\n')),(0,t.yg)("h2",{id:"retrieve-full-state-dump"},"Retrieve full state dump"),(0,t.yg)("p",null,"Endpoint to retrieve the following information in a single response:"),(0,t.yg)("ul",null,(0,t.yg)("li",{parentName:"ul"},"Current timestamp (Unix timestamp in nanosecond)"),(0,t.yg)("li",{parentName:"ul"},"List of partitions"),(0,t.yg)("li",{parentName:"ul"},"List of applications (running, completed and rejected)"),(0,t.yg)("li",{parentName:"ul"},"Application history"),(0,t.yg)("li",{parentName:"ul"},"Nodes"),(0,t.yg)("li",{parentName:"ul"},"Generic cluster information"),(0,t.yg)("li",{parentName:"ul"},"Container history"),(0,t.yg)("li",{parentName:"ul"},"Queues"),(0,t.yg)("li",{parentName:"ul"},"RMDiagnostics"),(0,t.yg)("li",{parentName:"ul"},"Log level"),(0,t.yg)("li",{parentName:"ul"},"Configuration")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/fullstatedump")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Method")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("h3",{id:"success-response-20"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("p",null,"The output of this REST query can be rather large, and it is a combination of those which have already been demonstrated."),(0,t.yg)("p",null,"The ",(0,t.yg)("inlineCode",{parentName:"p"},"RMDiagnostics")," shows the content of the K8Shim cache. The exact content is version dependent and has not stabilised.\nThe current content shows the cached objects:"),(0,t.yg)("ul",null,(0,t.yg)("li",{parentName:"ul"},"nodes"),(0,t.yg)("li",{parentName:"ul"},"pods"),(0,t.yg)("li",{parentName:"ul"},"priorityClasses"),(0,t.yg)("li",{parentName:"ul"},"schedulingState (pod status)")),(0,t.yg)("h3",{id:"failure-response"},"Failure response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code"),": ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("h2",{id:"batch-events"},"Batch Events"),(0,t.yg)("p",null,"Endpoint is used to retrieve a batch of event records."),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL"),": ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/events/batch")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"METHOD")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL query parameters")," :"),(0,t.yg)("ul",null,(0,t.yg)("li",{parentName:"ul"},(0,t.yg)("inlineCode",{parentName:"li"},"count")," (optional) : Specifies the maxmem number of events to be included in the response."),(0,t.yg)("li",{parentName:"ul"},(0,t.yg)("inlineCode",{parentName:"li"},"start")," (optional) : Specifies the starting ID for retrieving events. If the specified ID is outside the ring buffer\n(too low or too high), the response will include the lowest and highest ID values with ",(0,t.yg)("inlineCode",{parentName:"li"},"EventRecords")," being empty. ")),(0,t.yg)("h3",{id:"success-response-21"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code"),": ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{\n "InstanceUUID": "400046c6-2180-41a2-9be1-1c251ab2c498",\n "LowestID": 0,\n "HighestID": 7,\n "EventRecords": [\n {\n "type": 3,\n "objectID": "yk8s-worker",\n "message": "schedulable: true",\n "timestampNano": 1701347180239597300,\n "eventChangeType": 1,\n "eventChangeDetail": 302,\n "resource": {}\n },\n {\n "type": 3,\n "objectID": "yk8s-worker",\n "message": "Node added to the scheduler",\n "timestampNano": 1701347180239650600,\n "eventChangeType": 2,\n "resource": {\n "resources": {\n "ephemeral-storage": {\n "value": 502921060352\n },\n "hugepages-1Gi": {},\n "hugepages-2Mi": {},\n "memory": {\n "value": 33424998400\n },\n "pods": {\n "value": 110\n },\n "vcore": {\n "value": 8000\n }\n }\n }\n }\n ]\n}\n')),(0,t.yg)("h3",{id:"error-response-15"},"Error response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")),(0,t.yg)("h3",{id:"event-stream"},"Event stream"),(0,t.yg)("p",null,"Creates a persistent HTTP connection for event streaming. New events are sent to the clients immediately, so unlike the batch interface, there is no need for polling.\nThe number of active connections is limited. The default setting is 100 connections total and 15 connections per host. The respective configmap properties are ",(0,t.yg)("inlineCode",{parentName:"p"},"event.maxStreams")," and ",(0,t.yg)("inlineCode",{parentName:"p"},"event.maxStreamsPerHost"),". "),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL"),": ",(0,t.yg)("inlineCode",{parentName:"p"},"/ws/v1/events/stream")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"METHOD")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"GET")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Auth required")," : NO"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"URL query parameters"),":"),(0,t.yg)("ul",null,(0,t.yg)("li",{parentName:"ul"},(0,t.yg)("inlineCode",{parentName:"li"},"count")," (optional) : Specifies the number of past events (those which have been generated before the connection establishment) to include in the response. Default value is 0.")),(0,t.yg)("h3",{id:"success-response-22"},"Success response"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code"),": ",(0,t.yg)("inlineCode",{parentName:"p"},"200 OK")),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Content examples")),(0,t.yg)("pre",null,(0,t.yg)("code",{parentName:"pre",className:"language-json"},'{"type":2,"objectID":"app-1","timestampNano":1708465452903045265,"eventChangeType":1,"eventChangeDetail":204,"resource":{}}\n{"type":2,"objectID":"app-1","timestampNano":1708465452903192898,"eventChangeType":2,"eventChangeDetail":201,"referenceID":"alloc-1","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n{"type":3,"objectID":"node-1:1234","timestampNano":1708465452903312146,"eventChangeType":2,"eventChangeDetail":303,"referenceID":"alloc-1","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n{"type":2,"objectID":"app-1","timestampNano":1708465452903474210,"eventChangeType":1,"eventChangeDetail":205,"resource":{}}\n{"type":5,"objectID":"testuser","timestampNano":1708465452903506166,"eventChangeType":2,"eventChangeDetail":603,"referenceID":"root.singleleaf","resource":{"resources":{"memory":{"value":10000000},"vcore":{"value":1000}}}}\n')),(0,t.yg)("h3",{id:"error-responses"},"Error responses"),(0,t.yg)("p",null,(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"400 Bad Request")," (URL query is invalid)\n",(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"503 Service Unavailable")," (Too many active streaming connections)\n",(0,t.yg)("strong",{parentName:"p"},"Code")," : ",(0,t.yg)("inlineCode",{parentName:"p"},"500 Internal Server Error")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.51c7997e.js b/assets/js/935f2afb.51c7997e.js new file mode 100644 index 00000000000..2363047f900 --- /dev/null +++ b/assets/js/935f2afb.51c7997e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[98581],{35610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"Get Started","items":[{"type":"link","label":"Get Started","href":"/docs/next/","docId":"get_started/user_guide"},{"type":"link","label":"Features","href":"/docs/next/get_started/core_features","docId":"get_started/core_features"},{"type":"link","label":"Version details","href":"/docs/next/get_started/version","docId":"get_started/version"}],"collapsed":true,"collapsible":true},{"type":"category","label":"User Guide","items":[{"type":"link","label":"Deployment Modes","href":"/docs/next/user_guide/deployment_modes","docId":"user_guide/deployment_modes"},{"type":"link","label":"Service Configuration","href":"/docs/next/user_guide/service_config","docId":"user_guide/service_config"},{"type":"link","label":"Partition and Queue Configuration","href":"/docs/next/user_guide/queue_config","docId":"user_guide/queue_config"},{"type":"link","label":"App Placement Rules","href":"/docs/next/user_guide/placement_rules","docId":"user_guide/placement_rules"},{"type":"link","label":"User & Group Resolution","href":"/docs/next/user_guide/usergroup_resolution","docId":"user_guide/usergroup_resolution"},{"type":"link","label":"Sorting Policies","href":"/docs/next/user_guide/sorting_policies","docId":"user_guide/sorting_policies"},{"type":"link","label":"App & Queue Priorities","href":"/docs/next/user_guide/priorities","docId":"user_guide/priorities"},{"type":"link","label":"Preemption","href":"/docs/next/user_guide/preemption_cases","docId":"user_guide/preemption_cases"},{"type":"link","label":"ACLs","href":"/docs/next/user_guide/acls","docId":"user_guide/acls"},{"type":"link","label":"Resource Quota Management","href":"/docs/next/user_guide/resource_quota_management","docId":"user_guide/resource_quota_management"},{"type":"link","label":"Gang Scheduling","href":"/docs/next/user_guide/gang_scheduling","docId":"user_guide/gang_scheduling"},{"type":"link","label":"Labels and Annotations in YuniKorn","href":"/docs/next/user_guide/labels_and_annotations_in_yunikorn","docId":"user_guide/labels_and_annotations_in_yunikorn"},{"type":"link","label":"Prometheus and Grafana","href":"/docs/next/user_guide/prometheus","docId":"user_guide/prometheus"},{"type":"link","label":"Use Cases","href":"/docs/next/user_guide/use_cases","docId":"user_guide/use_cases"},{"type":"category","label":"Workloads","items":[{"type":"link","label":"Overview","href":"/docs/next/user_guide/workloads/workload_overview","docId":"user_guide/workloads/workload_overview"},{"type":"link","label":"Run NVIDIA GPU Jobs","href":"/docs/next/user_guide/workloads/run_nvidia","docId":"user_guide/workloads/run_nvidia"},{"type":"link","label":"Run Spark Jobs","href":"/docs/next/user_guide/workloads/run_spark","docId":"user_guide/workloads/run_spark"},{"type":"link","label":"Run Flink Jobs","href":"/docs/next/user_guide/workloads/run_flink","docId":"user_guide/workloads/run_flink"},{"type":"link","label":"Run TensorFlow Jobs","href":"/docs/next/user_guide/workloads/run_tf","docId":"user_guide/workloads/run_tf"},{"type":"link","label":"Run MPI Jobs","href":"/docs/next/user_guide/workloads/run_mpi","docId":"user_guide/workloads/run_mpi"}],"collapsed":true,"collapsible":true},{"type":"category","label":"REST APIs","items":[{"type":"link","label":"Cluster","href":"/docs/next/api/cluster","docId":"api/cluster"},{"type":"link","label":"Scheduler","href":"/docs/next/api/scheduler","docId":"api/scheduler"},{"type":"link","label":"System","href":"/docs/next/api/system","docId":"api/system"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Metrics for Prometheus","items":[{"type":"link","label":"Scheduler","href":"/docs/next/metrics/scheduler","docId":"metrics/scheduler"},{"type":"link","label":"Runtime","href":"/docs/next/metrics/runtime","docId":"metrics/runtime"},{"type":"link","label":"Queue","href":"/docs/next/metrics/queue","docId":"metrics/queue"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Troubleshooting","href":"/docs/next/user_guide/troubleshooting","docId":"user_guide/troubleshooting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Developer Guide","items":[{"type":"link","label":"Dev Environment Setup","href":"/docs/next/developer_guide/env_setup","docId":"developer_guide/env_setup"},{"type":"link","label":"Build and Run","href":"/docs/next/developer_guide/build","docId":"developer_guide/build"},{"type":"link","label":"Go module updates","href":"/docs/next/developer_guide/dependencies","docId":"developer_guide/dependencies"},{"type":"link","label":"Deploy to Kubernetes","href":"/docs/next/developer_guide/deployment","docId":"developer_guide/deployment"},{"type":"link","label":"Development in CodeReady Containers","href":"/docs/next/developer_guide/openshift_development","docId":"developer_guide/openshift_development"},{"type":"link","label":"Scheduler Object States","href":"/docs/next/developer_guide/scheduler_object_states","docId":"developer_guide/scheduler_object_states"},{"type":"category","label":"Designs","items":[{"type":"link","label":"Architecture","href":"/docs/next/design/architecture","docId":"design/architecture"},{"type":"link","label":"K8s Scheduler Plugin","href":"/docs/next/design/scheduler_plugin","docId":"design/scheduler_plugin"},{"type":"link","label":"Gang scheduling design","href":"/docs/next/design/gang_scheduling","docId":"design/gang_scheduling"},{"type":"link","label":"User/Group handling and lookup design","href":"/docs/next/design/user_group","docId":"design/user_group"},{"type":"link","label":"User Based Resource Usage Tracking","href":"/docs/next/design/user_based_resource_usage_tracking","docId":"design/user_based_resource_usage_tracking"},{"type":"link","label":"User Based Quota Enforcement","href":"/docs/next/design/user_group_resource_usage_enforcement","docId":"design/user_group_resource_usage_enforcement"},{"type":"link","label":"Historical Usage Tracking","href":"/docs/next/design/historical_usage_tracking","docId":"design/historical_usage_tracking"},{"type":"link","label":"Simplifying Interface Messages","href":"/docs/next/design/interface_message_simplification","docId":"design/interface_message_simplification"},{"type":"link","label":"Scheduler cache removal design","href":"/docs/next/design/cache_removal","docId":"design/cache_removal"},{"type":"link","label":"Preemption","href":"/docs/next/design/preemption","docId":"design/preemption"},{"type":"link","label":"DaemonSet Scheduling using Simple Preemptor","href":"/docs/next/design/simple_preemptor","docId":"design/simple_preemptor"},{"type":"link","label":"Generic Resource Types in Namespace Quota","href":"/docs/next/design/generic_resource","docId":"design/generic_resource"},{"type":"link","label":"Priority Scheduling","href":"/docs/next/design/priority_scheduling","docId":"design/priority_scheduling"},{"type":"link","label":"Resilience","href":"/docs/next/design/resilience","docId":"design/resilience"},{"type":"link","label":"Configuration V2","href":"/docs/next/design/config_v2","docId":"design/config_v2"},{"type":"link","label":"Scheduler Configuration","href":"/docs/next/design/scheduler_configuration","docId":"design/scheduler_configuration"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Archived Designs","items":[{"type":"link","label":"Kubernetes Shim Design","href":"/docs/next/archived_design/k8shim","docId":"archived_design/k8shim"},{"type":"link","label":"Namespace Resource Quota","href":"/docs/next/archived_design/namespace_resource_quota","docId":"archived_design/namespace_resource_quota"},{"type":"link","label":"Support K8s Predicates","href":"/docs/next/archived_design/predicates","docId":"archived_design/predicates"},{"type":"link","label":"Scheduler Core Design","href":"/docs/next/archived_design/scheduler_core_design","docId":"archived_design/scheduler_core_design"},{"type":"link","label":"Batch Workloads Ordering with StateAware Policy","href":"/docs/next/archived_design/state_aware_scheduling","docId":"archived_design/state_aware_scheduling"},{"type":"link","label":"Cross Queue Preemption","href":"/docs/next/archived_design/cross_queue_preemption","docId":"archived_design/cross_queue_preemption"},{"type":"link","label":"Pluggable App Management","href":"/docs/next/archived_design/pluggable_app_management","docId":"archived_design/pluggable_app_management"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Performance","items":[{"type":"link","label":"Evaluate YuniKorn Performance with Kubemark","href":"/docs/next/performance/evaluate_perf_function_with_kubemark","docId":"performance/evaluate_perf_function_with_kubemark"},{"type":"link","label":"Evaluate YuniKorn Performance with KWOK","href":"/docs/next/performance/evaluate_perf_function_with_kwok","docId":"performance/evaluate_perf_function_with_kwok"},{"type":"link","label":"Benchmarking Tutorial","href":"/docs/next/performance/performance_tutorial","docId":"performance/performance_tutorial"},{"type":"link","label":"Scheduler Metrics","href":"/docs/next/performance/metrics","docId":"performance/metrics"},{"type":"link","label":"Profiling","href":"/docs/next/performance/profiling","docId":"performance/profiling"}],"collapsed":true,"collapsible":true}]},"docs":{"api/cluster":{"id":"api/cluster","title":"Cluster","description":"\x3c!--","sidebar":"docs"},"api/scheduler":{"id":"api/scheduler","title":"Scheduler","description":"\x3c!--","sidebar":"docs"},"api/system":{"id":"api/system","title":"System","description":"\x3c!--","sidebar":"docs"},"archived_design/cross_queue_preemption":{"id":"archived_design/cross_queue_preemption","title":"Cross Queue Preemption","description":"\x3c!--","sidebar":"docs"},"archived_design/k8shim":{"id":"archived_design/k8shim","title":"Kubernetes Shim Design","description":"\x3c!--","sidebar":"docs"},"archived_design/namespace_resource_quota":{"id":"archived_design/namespace_resource_quota","title":"Namespace Resource Quota","description":"\x3c!--","sidebar":"docs"},"archived_design/pluggable_app_management":{"id":"archived_design/pluggable_app_management","title":"Pluggable App Management","description":"\x3c!--","sidebar":"docs"},"archived_design/predicates":{"id":"archived_design/predicates","title":"Support K8s Predicates","description":"\x3c!--","sidebar":"docs"},"archived_design/scheduler_core_design":{"id":"archived_design/scheduler_core_design","title":"Scheduler Core Design","description":"\x3c!--","sidebar":"docs"},"archived_design/state_aware_scheduling":{"id":"archived_design/state_aware_scheduling","title":"Batch Workloads Ordering with StateAware Policy","description":"\x3c!--","sidebar":"docs"},"design/architecture":{"id":"design/architecture","title":"Architecture","description":"\x3c!--","sidebar":"docs"},"design/cache_removal":{"id":"design/cache_removal","title":"Scheduler cache removal design","description":"\x3c!--","sidebar":"docs"},"design/config_v2":{"id":"design/config_v2","title":"Configuration V2","description":"\x3c!--","sidebar":"docs"},"design/gang_scheduling":{"id":"design/gang_scheduling","title":"Gang scheduling design","description":"\x3c!--","sidebar":"docs"},"design/generic_resource":{"id":"design/generic_resource","title":"Generic Resource Types in Namespace Quota","description":"\x3c!--","sidebar":"docs"},"design/historical_usage_tracking":{"id":"design/historical_usage_tracking","title":"Historical Usage Tracking","description":"\x3c!--","sidebar":"docs"},"design/interface_message_simplification":{"id":"design/interface_message_simplification","title":"Simplifying Interface Messages","description":"\x3c!--","sidebar":"docs"},"design/preemption":{"id":"design/preemption","title":"Preemption","description":"\x3c!--","sidebar":"docs"},"design/priority_scheduling":{"id":"design/priority_scheduling","title":"Priority Scheduling","description":"\x3c!--","sidebar":"docs"},"design/resilience":{"id":"design/resilience","title":"Resilience","description":"\x3c!--","sidebar":"docs"},"design/scheduler_configuration":{"id":"design/scheduler_configuration","title":"Scheduler Configuration","description":"\x3c!--","sidebar":"docs"},"design/scheduler_plugin":{"id":"design/scheduler_plugin","title":"K8s Scheduler Plugin","description":"\x3c!--","sidebar":"docs"},"design/simple_preemptor":{"id":"design/simple_preemptor","title":"DaemonSet Scheduling using Simple Preemptor","description":"\x3c!--","sidebar":"docs"},"design/user_based_resource_usage_tracking":{"id":"design/user_based_resource_usage_tracking","title":"User Based Resource Usage Tracking","description":"\x3c!--","sidebar":"docs"},"design/user_group":{"id":"design/user_group","title":"User/Group handling and lookup design","description":"\x3c!--","sidebar":"docs"},"design/user_group_resource_usage_enforcement":{"id":"design/user_group_resource_usage_enforcement","title":"User Based Quota Enforcement","description":"\x3c!--","sidebar":"docs"},"developer_guide/build":{"id":"developer_guide/build","title":"Build and Run","description":"\x3c!--","sidebar":"docs"},"developer_guide/dependencies":{"id":"developer_guide/dependencies","title":"Go module updates","description":"\x3c!--","sidebar":"docs"},"developer_guide/deployment":{"id":"developer_guide/deployment","title":"Deploy to Kubernetes","description":"\x3c!--","sidebar":"docs"},"developer_guide/env_setup":{"id":"developer_guide/env_setup","title":"Dev Environment Setup","description":"\x3c!--","sidebar":"docs"},"developer_guide/openshift_development":{"id":"developer_guide/openshift_development","title":"Development in CodeReady Containers","description":"\x3c!--","sidebar":"docs"},"developer_guide/scheduler_object_states":{"id":"developer_guide/scheduler_object_states","title":"Scheduler Object States","description":"\x3c!--","sidebar":"docs"},"get_started/core_features":{"id":"get_started/core_features","title":"Features","description":"\x3c!--","sidebar":"docs"},"get_started/user_guide":{"id":"get_started/user_guide","title":"Get Started","description":"\x3c!--","sidebar":"docs"},"get_started/version":{"id":"get_started/version","title":"Version details","description":"\x3c!--","sidebar":"docs"},"metrics/queue":{"id":"metrics/queue","title":"Queue","description":"\x3c!--","sidebar":"docs"},"metrics/runtime":{"id":"metrics/runtime","title":"Runtime","description":"\x3c!--","sidebar":"docs"},"metrics/scheduler":{"id":"metrics/scheduler","title":"Scheduler","description":"\x3c!--","sidebar":"docs"},"performance/evaluate_perf_function_with_kubemark":{"id":"performance/evaluate_perf_function_with_kubemark","title":"Evaluate YuniKorn Performance with Kubemark","description":"\x3c!--","sidebar":"docs"},"performance/evaluate_perf_function_with_kwok":{"id":"performance/evaluate_perf_function_with_kwok","title":"Evaluate YuniKorn Performance with KWOK","description":"\x3c!--","sidebar":"docs"},"performance/metrics":{"id":"performance/metrics","title":"Scheduler Metrics","description":"\x3c!--","sidebar":"docs"},"performance/performance_tutorial":{"id":"performance/performance_tutorial","title":"Benchmarking Tutorial","description":"\x3c!--","sidebar":"docs"},"performance/profiling":{"id":"performance/profiling","title":"Profiling","description":"\x3c!--","sidebar":"docs"},"user_guide/acls":{"id":"user_guide/acls","title":"ACLs","description":"\x3c!--","sidebar":"docs"},"user_guide/deployment_modes":{"id":"user_guide/deployment_modes","title":"Deployment Modes","description":"\x3c!--","sidebar":"docs"},"user_guide/gang_scheduling":{"id":"user_guide/gang_scheduling","title":"Gang Scheduling","description":"\x3c!--","sidebar":"docs"},"user_guide/labels_and_annotations_in_yunikorn":{"id":"user_guide/labels_and_annotations_in_yunikorn","title":"Labels and Annotations in YuniKorn","description":"\x3c!--","sidebar":"docs"},"user_guide/placement_rules":{"id":"user_guide/placement_rules","title":"App Placement Rules","description":"\x3c!--","sidebar":"docs"},"user_guide/preemption_cases":{"id":"user_guide/preemption_cases","title":"Preemption","description":"\x3c!--","sidebar":"docs"},"user_guide/priorities":{"id":"user_guide/priorities","title":"App & Queue Priorities","description":"\x3c!--","sidebar":"docs"},"user_guide/prometheus":{"id":"user_guide/prometheus","title":"Prometheus and Grafana","description":"\x3c!--","sidebar":"docs"},"user_guide/queue_config":{"id":"user_guide/queue_config","title":"Partition and Queue Configuration","description":"\x3c!--","sidebar":"docs"},"user_guide/resource_quota_management":{"id":"user_guide/resource_quota_management","title":"Resource Quota Management","description":"\x3c!--","sidebar":"docs"},"user_guide/service_config":{"id":"user_guide/service_config","title":"Service Configuration","description":"\x3c!--","sidebar":"docs"},"user_guide/sorting_policies":{"id":"user_guide/sorting_policies","title":"Sorting Policies","description":"\x3c!--","sidebar":"docs"},"user_guide/troubleshooting":{"id":"user_guide/troubleshooting","title":"Troubleshooting","description":"\x3c!--","sidebar":"docs"},"user_guide/use_cases":{"id":"user_guide/use_cases","title":"Use Cases","description":"\x3c!--","sidebar":"docs"},"user_guide/usergroup_resolution":{"id":"user_guide/usergroup_resolution","title":"User & Group Resolution","description":"\x3c!--","sidebar":"docs"},"user_guide/workloads/run_flink":{"id":"user_guide/workloads/run_flink","title":"Run Flink Jobs","description":"How to run Flink jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_mpi":{"id":"user_guide/workloads/run_mpi","title":"Run MPI Jobs","description":"How to run MPI jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_nvidia":{"id":"user_guide/workloads/run_nvidia","title":"Run NVIDIA GPU Jobs","description":"How to run generic example of GPU scheduling with Yunikorn.","sidebar":"docs"},"user_guide/workloads/run_spark":{"id":"user_guide/workloads/run_spark","title":"Run Spark Jobs","description":"How to run Spark jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_tf":{"id":"user_guide/workloads/run_tf","title":"Run TensorFlow Jobs","description":"How to run TensorFlow jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/workload_overview":{"id":"user_guide/workloads/workload_overview","title":"Overview","description":"\x3c!--","sidebar":"docs"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.7b072cfc.js b/assets/js/935f2afb.7b072cfc.js deleted file mode 100644 index b77781d5f86..00000000000 --- a/assets/js/935f2afb.7b072cfc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[98581],{35610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"Get Started","items":[{"type":"link","label":"Get Started","href":"/docs/next/","docId":"get_started/user_guide"},{"type":"link","label":"Features","href":"/docs/next/get_started/core_features","docId":"get_started/core_features"},{"type":"link","label":"Version details","href":"/docs/next/get_started/version","docId":"get_started/version"}],"collapsed":true,"collapsible":true},{"type":"category","label":"User Guide","items":[{"type":"link","label":"Deployment Modes","href":"/docs/next/user_guide/deployment_modes","docId":"user_guide/deployment_modes"},{"type":"link","label":"Service Configuration","href":"/docs/next/user_guide/service_config","docId":"user_guide/service_config"},{"type":"link","label":"Partition and Queue Configuration","href":"/docs/next/user_guide/queue_config","docId":"user_guide/queue_config"},{"type":"link","label":"App Placement Rules","href":"/docs/next/user_guide/placement_rules","docId":"user_guide/placement_rules"},{"type":"link","label":"User & Group Resolution","href":"/docs/next/user_guide/usergroup_resolution","docId":"user_guide/usergroup_resolution"},{"type":"link","label":"Sorting Policies","href":"/docs/next/user_guide/sorting_policies","docId":"user_guide/sorting_policies"},{"type":"link","label":"App & Queue Priorities","href":"/docs/next/user_guide/priorities","docId":"user_guide/priorities"},{"type":"link","label":"Preemption","href":"/docs/next/user_guide/preemption_cases","docId":"user_guide/preemption_cases"},{"type":"link","label":"ACLs","href":"/docs/next/user_guide/acls","docId":"user_guide/acls"},{"type":"link","label":"Resource Quota Management","href":"/docs/next/user_guide/resource_quota_management","docId":"user_guide/resource_quota_management"},{"type":"link","label":"Gang Scheduling","href":"/docs/next/user_guide/gang_scheduling","docId":"user_guide/gang_scheduling"},{"type":"link","label":"Labels and Annotations in YuniKorn","href":"/docs/next/user_guide/labels_and_annotations_in_yunikorn","docId":"user_guide/labels_and_annotations_in_yunikorn"},{"type":"link","label":"Prometheus and Grafana","href":"/docs/next/user_guide/prometheus","docId":"user_guide/prometheus"},{"type":"link","label":"Use Cases","href":"/docs/next/user_guide/use_cases","docId":"user_guide/use_cases"},{"type":"category","label":"Workloads","items":[{"type":"link","label":"Overview","href":"/docs/next/user_guide/workloads/workload_overview","docId":"user_guide/workloads/workload_overview"},{"type":"link","label":"Run NVIDIA GPU Jobs","href":"/docs/next/user_guide/workloads/run_nvidia","docId":"user_guide/workloads/run_nvidia"},{"type":"link","label":"Run Spark Jobs","href":"/docs/next/user_guide/workloads/run_spark","docId":"user_guide/workloads/run_spark"},{"type":"link","label":"Run Flink Jobs","href":"/docs/next/user_guide/workloads/run_flink","docId":"user_guide/workloads/run_flink"},{"type":"link","label":"Run TensorFlow Jobs","href":"/docs/next/user_guide/workloads/run_tf","docId":"user_guide/workloads/run_tf"},{"type":"link","label":"Run MPI Jobs","href":"/docs/next/user_guide/workloads/run_mpi","docId":"user_guide/workloads/run_mpi"}],"collapsed":true,"collapsible":true},{"type":"category","label":"REST APIs","items":[{"type":"link","label":"Cluster","href":"/docs/next/api/cluster","docId":"api/cluster"},{"type":"link","label":"Scheduler","href":"/docs/next/api/scheduler","docId":"api/scheduler"},{"type":"link","label":"System","href":"/docs/next/api/system","docId":"api/system"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Metrics for Prometheus","items":[{"type":"link","label":"Scheduler","href":"/docs/next/metrics/scheduler","docId":"metrics/scheduler"},{"type":"link","label":"Runtime","href":"/docs/next/metrics/runtime","docId":"metrics/runtime"},{"type":"link","label":"Queue","href":"/docs/next/metrics/queue","docId":"metrics/queue"}],"collapsed":true,"collapsible":true},{"type":"link","label":"Troubleshooting","href":"/docs/next/user_guide/troubleshooting","docId":"user_guide/troubleshooting"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Developer Guide","items":[{"type":"link","label":"Dev Environment Setup","href":"/docs/next/developer_guide/env_setup","docId":"developer_guide/env_setup"},{"type":"link","label":"Build and Run","href":"/docs/next/developer_guide/build","docId":"developer_guide/build"},{"type":"link","label":"Go module updates","href":"/docs/next/developer_guide/dependencies","docId":"developer_guide/dependencies"},{"type":"link","label":"Deploy to Kubernetes","href":"/docs/next/developer_guide/deployment","docId":"developer_guide/deployment"},{"type":"link","label":"Development in CodeReady Containers","href":"/docs/next/developer_guide/openshift_development","docId":"developer_guide/openshift_development"},{"type":"link","label":"Scheduler Object States","href":"/docs/next/developer_guide/scheduler_object_states","docId":"developer_guide/scheduler_object_states"},{"type":"category","label":"Designs","items":[{"type":"link","label":"Architecture","href":"/docs/next/design/architecture","docId":"design/architecture"},{"type":"link","label":"K8s Scheduler Plugin","href":"/docs/next/design/scheduler_plugin","docId":"design/scheduler_plugin"},{"type":"link","label":"Gang scheduling design","href":"/docs/next/design/gang_scheduling","docId":"design/gang_scheduling"},{"type":"link","label":"User/Group handling and lookup design","href":"/docs/next/design/user_group","docId":"design/user_group"},{"type":"link","label":"User Based Resource Usage Tracking","href":"/docs/next/design/user_based_resource_usage_tracking","docId":"design/user_based_resource_usage_tracking"},{"type":"link","label":"User Based Quota Enforcement","href":"/docs/next/design/user_group_resource_usage_enforcement","docId":"design/user_group_resource_usage_enforcement"},{"type":"link","label":"Historical Usage Tracking","href":"/docs/next/design/historical_usage_tracking","docId":"design/historical_usage_tracking"},{"type":"link","label":"Simplifying Interface Messages","href":"/docs/next/design/interface_message_simplification","docId":"design/interface_message_simplification"},{"type":"link","label":"Scheduler cache removal design","href":"/docs/next/design/cache_removal","docId":"design/cache_removal"},{"type":"link","label":"Preemption","href":"/docs/next/design/preemption","docId":"design/preemption"},{"type":"link","label":"DaemonSet Scheduling using Simple Preemptor","href":"/docs/next/design/simple_preemptor","docId":"design/simple_preemptor"},{"type":"link","label":"Generic Resource Types in Namespace Quota","href":"/docs/next/design/generic_resource","docId":"design/generic_resource"},{"type":"link","label":"Priority Scheduling","href":"/docs/next/design/priority_scheduling","docId":"design/priority_scheduling"},{"type":"link","label":"Resilience","href":"/docs/next/design/resilience","docId":"design/resilience"},{"type":"link","label":"Batch Workloads Ordering with StateAware Policy","href":"/docs/next/design/state_aware_scheduling","docId":"design/state_aware_scheduling"},{"type":"link","label":"Configuration V2","href":"/docs/next/design/config_v2","docId":"design/config_v2"},{"type":"link","label":"Scheduler Configuration","href":"/docs/next/design/scheduler_configuration","docId":"design/scheduler_configuration"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Archived Designs","items":[{"type":"link","label":"Kubernetes Shim Design","href":"/docs/next/archived_design/k8shim","docId":"archived_design/k8shim"},{"type":"link","label":"Namespace Resource Quota","href":"/docs/next/archived_design/namespace_resource_quota","docId":"archived_design/namespace_resource_quota"},{"type":"link","label":"Support K8s Predicates","href":"/docs/next/archived_design/predicates","docId":"archived_design/predicates"},{"type":"link","label":"Scheduler Core Design","href":"/docs/next/archived_design/scheduler_core_design","docId":"archived_design/scheduler_core_design"},{"type":"link","label":"Cross Queue Preemption","href":"/docs/next/archived_design/cross_queue_preemption","docId":"archived_design/cross_queue_preemption"},{"type":"link","label":"Pluggable App Management","href":"/docs/next/archived_design/pluggable_app_management","docId":"archived_design/pluggable_app_management"}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"Performance","items":[{"type":"link","label":"Evaluate YuniKorn Performance with Kubemark","href":"/docs/next/performance/evaluate_perf_function_with_kubemark","docId":"performance/evaluate_perf_function_with_kubemark"},{"type":"link","label":"Evaluate YuniKorn Performance with KWOK","href":"/docs/next/performance/evaluate_perf_function_with_kwok","docId":"performance/evaluate_perf_function_with_kwok"},{"type":"link","label":"Benchmarking Tutorial","href":"/docs/next/performance/performance_tutorial","docId":"performance/performance_tutorial"},{"type":"link","label":"Scheduler Metrics","href":"/docs/next/performance/metrics","docId":"performance/metrics"},{"type":"link","label":"Profiling","href":"/docs/next/performance/profiling","docId":"performance/profiling"}],"collapsed":true,"collapsible":true}]},"docs":{"api/cluster":{"id":"api/cluster","title":"Cluster","description":"\x3c!--","sidebar":"docs"},"api/scheduler":{"id":"api/scheduler","title":"Scheduler","description":"\x3c!--","sidebar":"docs"},"api/system":{"id":"api/system","title":"System","description":"\x3c!--","sidebar":"docs"},"archived_design/cross_queue_preemption":{"id":"archived_design/cross_queue_preemption","title":"Cross Queue Preemption","description":"\x3c!--","sidebar":"docs"},"archived_design/k8shim":{"id":"archived_design/k8shim","title":"Kubernetes Shim Design","description":"\x3c!--","sidebar":"docs"},"archived_design/namespace_resource_quota":{"id":"archived_design/namespace_resource_quota","title":"Namespace Resource Quota","description":"\x3c!--","sidebar":"docs"},"archived_design/pluggable_app_management":{"id":"archived_design/pluggable_app_management","title":"Pluggable App Management","description":"\x3c!--","sidebar":"docs"},"archived_design/predicates":{"id":"archived_design/predicates","title":"Support K8s Predicates","description":"\x3c!--","sidebar":"docs"},"archived_design/scheduler_core_design":{"id":"archived_design/scheduler_core_design","title":"Scheduler Core Design","description":"\x3c!--","sidebar":"docs"},"design/architecture":{"id":"design/architecture","title":"Architecture","description":"\x3c!--","sidebar":"docs"},"design/cache_removal":{"id":"design/cache_removal","title":"Scheduler cache removal design","description":"\x3c!--","sidebar":"docs"},"design/config_v2":{"id":"design/config_v2","title":"Configuration V2","description":"\x3c!--","sidebar":"docs"},"design/gang_scheduling":{"id":"design/gang_scheduling","title":"Gang scheduling design","description":"\x3c!--","sidebar":"docs"},"design/generic_resource":{"id":"design/generic_resource","title":"Generic Resource Types in Namespace Quota","description":"\x3c!--","sidebar":"docs"},"design/historical_usage_tracking":{"id":"design/historical_usage_tracking","title":"Historical Usage Tracking","description":"\x3c!--","sidebar":"docs"},"design/interface_message_simplification":{"id":"design/interface_message_simplification","title":"Simplifying Interface Messages","description":"\x3c!--","sidebar":"docs"},"design/preemption":{"id":"design/preemption","title":"Preemption","description":"\x3c!--","sidebar":"docs"},"design/priority_scheduling":{"id":"design/priority_scheduling","title":"Priority Scheduling","description":"\x3c!--","sidebar":"docs"},"design/resilience":{"id":"design/resilience","title":"Resilience","description":"\x3c!--","sidebar":"docs"},"design/scheduler_configuration":{"id":"design/scheduler_configuration","title":"Scheduler Configuration","description":"\x3c!--","sidebar":"docs"},"design/scheduler_plugin":{"id":"design/scheduler_plugin","title":"K8s Scheduler Plugin","description":"\x3c!--","sidebar":"docs"},"design/simple_preemptor":{"id":"design/simple_preemptor","title":"DaemonSet Scheduling using Simple Preemptor","description":"\x3c!--","sidebar":"docs"},"design/state_aware_scheduling":{"id":"design/state_aware_scheduling","title":"Batch Workloads Ordering with StateAware Policy","description":"\x3c!--","sidebar":"docs"},"design/user_based_resource_usage_tracking":{"id":"design/user_based_resource_usage_tracking","title":"User Based Resource Usage Tracking","description":"\x3c!--","sidebar":"docs"},"design/user_group":{"id":"design/user_group","title":"User/Group handling and lookup design","description":"\x3c!--","sidebar":"docs"},"design/user_group_resource_usage_enforcement":{"id":"design/user_group_resource_usage_enforcement","title":"User Based Quota Enforcement","description":"\x3c!--","sidebar":"docs"},"developer_guide/build":{"id":"developer_guide/build","title":"Build and Run","description":"\x3c!--","sidebar":"docs"},"developer_guide/dependencies":{"id":"developer_guide/dependencies","title":"Go module updates","description":"\x3c!--","sidebar":"docs"},"developer_guide/deployment":{"id":"developer_guide/deployment","title":"Deploy to Kubernetes","description":"\x3c!--","sidebar":"docs"},"developer_guide/env_setup":{"id":"developer_guide/env_setup","title":"Dev Environment Setup","description":"\x3c!--","sidebar":"docs"},"developer_guide/openshift_development":{"id":"developer_guide/openshift_development","title":"Development in CodeReady Containers","description":"\x3c!--","sidebar":"docs"},"developer_guide/scheduler_object_states":{"id":"developer_guide/scheduler_object_states","title":"Scheduler Object States","description":"\x3c!--","sidebar":"docs"},"get_started/core_features":{"id":"get_started/core_features","title":"Features","description":"\x3c!--","sidebar":"docs"},"get_started/user_guide":{"id":"get_started/user_guide","title":"Get Started","description":"\x3c!--","sidebar":"docs"},"get_started/version":{"id":"get_started/version","title":"Version details","description":"\x3c!--","sidebar":"docs"},"metrics/queue":{"id":"metrics/queue","title":"Queue","description":"\x3c!--","sidebar":"docs"},"metrics/runtime":{"id":"metrics/runtime","title":"Runtime","description":"\x3c!--","sidebar":"docs"},"metrics/scheduler":{"id":"metrics/scheduler","title":"Scheduler","description":"\x3c!--","sidebar":"docs"},"performance/evaluate_perf_function_with_kubemark":{"id":"performance/evaluate_perf_function_with_kubemark","title":"Evaluate YuniKorn Performance with Kubemark","description":"\x3c!--","sidebar":"docs"},"performance/evaluate_perf_function_with_kwok":{"id":"performance/evaluate_perf_function_with_kwok","title":"Evaluate YuniKorn Performance with KWOK","description":"\x3c!--","sidebar":"docs"},"performance/metrics":{"id":"performance/metrics","title":"Scheduler Metrics","description":"\x3c!--","sidebar":"docs"},"performance/performance_tutorial":{"id":"performance/performance_tutorial","title":"Benchmarking Tutorial","description":"\x3c!--","sidebar":"docs"},"performance/profiling":{"id":"performance/profiling","title":"Profiling","description":"\x3c!--","sidebar":"docs"},"user_guide/acls":{"id":"user_guide/acls","title":"ACLs","description":"\x3c!--","sidebar":"docs"},"user_guide/deployment_modes":{"id":"user_guide/deployment_modes","title":"Deployment Modes","description":"\x3c!--","sidebar":"docs"},"user_guide/gang_scheduling":{"id":"user_guide/gang_scheduling","title":"Gang Scheduling","description":"\x3c!--","sidebar":"docs"},"user_guide/labels_and_annotations_in_yunikorn":{"id":"user_guide/labels_and_annotations_in_yunikorn","title":"Labels and Annotations in YuniKorn","description":"\x3c!--","sidebar":"docs"},"user_guide/placement_rules":{"id":"user_guide/placement_rules","title":"App Placement Rules","description":"\x3c!--","sidebar":"docs"},"user_guide/preemption_cases":{"id":"user_guide/preemption_cases","title":"Preemption","description":"\x3c!--","sidebar":"docs"},"user_guide/priorities":{"id":"user_guide/priorities","title":"App & Queue Priorities","description":"\x3c!--","sidebar":"docs"},"user_guide/prometheus":{"id":"user_guide/prometheus","title":"Prometheus and Grafana","description":"\x3c!--","sidebar":"docs"},"user_guide/queue_config":{"id":"user_guide/queue_config","title":"Partition and Queue Configuration","description":"\x3c!--","sidebar":"docs"},"user_guide/resource_quota_management":{"id":"user_guide/resource_quota_management","title":"Resource Quota Management","description":"\x3c!--","sidebar":"docs"},"user_guide/service_config":{"id":"user_guide/service_config","title":"Service Configuration","description":"\x3c!--","sidebar":"docs"},"user_guide/sorting_policies":{"id":"user_guide/sorting_policies","title":"Sorting Policies","description":"\x3c!--","sidebar":"docs"},"user_guide/troubleshooting":{"id":"user_guide/troubleshooting","title":"Troubleshooting","description":"\x3c!--","sidebar":"docs"},"user_guide/use_cases":{"id":"user_guide/use_cases","title":"Use Cases","description":"\x3c!--","sidebar":"docs"},"user_guide/usergroup_resolution":{"id":"user_guide/usergroup_resolution","title":"User & Group Resolution","description":"\x3c!--","sidebar":"docs"},"user_guide/workloads/run_flink":{"id":"user_guide/workloads/run_flink","title":"Run Flink Jobs","description":"How to run Flink jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_mpi":{"id":"user_guide/workloads/run_mpi","title":"Run MPI Jobs","description":"How to run MPI jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_nvidia":{"id":"user_guide/workloads/run_nvidia","title":"Run NVIDIA GPU Jobs","description":"How to run generic example of GPU scheduling with Yunikorn.","sidebar":"docs"},"user_guide/workloads/run_spark":{"id":"user_guide/workloads/run_spark","title":"Run Spark Jobs","description":"How to run Spark jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/run_tf":{"id":"user_guide/workloads/run_tf","title":"Run TensorFlow Jobs","description":"How to run TensorFlow jobs with YuniKorn","sidebar":"docs"},"user_guide/workloads/workload_overview":{"id":"user_guide/workloads/workload_overview","title":"Overview","description":"\x3c!--","sidebar":"docs"}}}')}}]); \ No newline at end of file diff --git a/assets/js/afe6f65e.5e55a1e2.js b/assets/js/afe6f65e.5e55a1e2.js new file mode 100644 index 00000000000..4dbb3ef372f --- /dev/null +++ b/assets/js/afe6f65e.5e55a1e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[35173],{58860:(e,n,i)=>{i.d(n,{xA:()=>u,yg:()=>h});var t=i(37953);function o(e,n,i){return n in e?Object.defineProperty(e,n,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[n]=i,e}function a(e,n){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),i.push.apply(i,t)}return i}function r(e){for(var n=1;n=0||(o[i]=e[i]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(o[i]=e[i])}return o}var s=t.createContext({}),p=function(e){var n=t.useContext(s),i=n;return e&&(i="function"==typeof e?e(n):r(r({},n),e)),i},u=function(e){var n=p(e.components);return t.createElement(s.Provider,{value:n},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var i=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(i),d=o,h=c["".concat(s,".").concat(d)]||c[d]||g[d]||a;return i?t.createElement(h,r(r({ref:n},u),{},{components:i})):t.createElement(h,r({ref:n},u))}));function h(e,n){var i=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=i.length,r=new Array(a);r[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[c]="string"==typeof e?e:o,r[1]=l;for(var p=2;p{i.r(n),i.d(n,{assets:()=>s,contentTitle:()=>r,default:()=>g,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var t=i(72994),o=(i(37953),i(58860));const a={id:"sorting_policies",title:"Sorting Policies"},r=void 0,l={unversionedId:"user_guide/sorting_policies",id:"user_guide/sorting_policies",title:"Sorting Policies",description:"\x3c!--",source:"@site/docs/user_guide/sorting_policies.md",sourceDirName:"user_guide",slug:"/user_guide/sorting_policies",permalink:"/docs/next/user_guide/sorting_policies",draft:!1,tags:[],version:"current",frontMatter:{id:"sorting_policies",title:"Sorting Policies"},sidebar:"docs",previous:{title:"User & Group Resolution",permalink:"/docs/next/user_guide/usergroup_resolution"},next:{title:"App & Queue Priorities",permalink:"/docs/next/user_guide/priorities"}},s={},p=[{value:"Application sorting",id:"application-sorting",level:2},{value:"FifoSortPolicy",id:"fifosortpolicy",level:3},{value:"FairSortPolicy",id:"fairsortpolicy",level:3},{value:"Node sorting",id:"node-sorting",level:2},{value:"FairnessPolicy",id:"fairnesspolicy",level:3},{value:"BinPackingPolicy",id:"binpackingpolicy",level:3},{value:"Resource weighting",id:"resource-weighting",level:2},{value:"Request sorting",id:"request-sorting",level:2}],u={toc:p},c="wrapper";function g(e){let{components:n,...i}=e;return(0,o.yg)(c,(0,t.A)({},u,i,{components:n,mdxType:"MDXLayout"}),(0,o.yg)("p",null,"The scheduler uses policies allow changing the scheduling behaviour without code changes.\nPolicies can be set for:"),(0,o.yg)("ul",null,(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("a",{parentName:"li",href:"#application-sorting"},"Applications")),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("a",{parentName:"li",href:"#node-sorting"},"Nodes")),(0,o.yg)("li",{parentName:"ul"},(0,o.yg)("a",{parentName:"li",href:"#request-sorting"},"Requests"))),(0,o.yg)("h2",{id:"application-sorting"},"Application sorting"),(0,o.yg)("p",null,"The application sorting policy is set for each queue via the config.\nA sorting policy setting is only effective on a ",(0,o.yg)("em",{parentName:"p"},"leaf")," queue.\nEach ",(0,o.yg)("em",{parentName:"p"},"leaf")," queue can use a different policy."),(0,o.yg)("p",null,"A sorting policy only specifies the order in which the applications are sorted within a queue.\nThat order is crucial in specifying which application is considered first when assigning resources.\nSorting policies do ",(0,o.yg)("em",{parentName:"p"},"not")," affect the number of applications that are scheduled or active in the queue at the same time.\nAll applications that have pending resource requests can and will be scheduled in a queue unless specifically filtered out.\nEven when applications are sorted using a first in first out policy multiple applications will run in a queue in parallel. "),(0,o.yg)("p",null,"A ",(0,o.yg)("em",{parentName:"p"},"parent")," queue will always use the fair policy to sort the child queues."),(0,o.yg)("p",null,"The relative priority of child queues (in the case of ",(0,o.yg)("em",{parentName:"p"},"parent")," queue sorting)\nand applications (in the case of ",(0,o.yg)("em",{parentName:"p"},"leaf")," queue sorting) will be considered first.\nTo ignore application and queue priorities when scheduling, set the queue\nproperty ",(0,o.yg)("inlineCode",{parentName:"p"},"application.sort.priority")," to ",(0,o.yg)("inlineCode",{parentName:"p"},"disabled"),"."),(0,o.yg)("p",null,"The following configuration entry sets the application sorting policy to ",(0,o.yg)("inlineCode",{parentName:"p"},"fifo")," for the queue ",(0,o.yg)("inlineCode",{parentName:"p"},"root.sandbox"),": "),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: sandbox\n properties:\n application.sort.policy: fifo\n")),(0,o.yg)("p",null,"The only applications that are considered during scheduling must have outstanding requests.\nA filter is applied ",(0,o.yg)("em",{parentName:"p"},"while")," sorting the applications to remove all that do not have outstanding requests."),(0,o.yg)("h3",{id:"fifosortpolicy"},"FifoSortPolicy"),(0,o.yg)("p",null,"Short description: first in first out, based on application create time "),(0,o.yg)("p",null,"Config value: ",(0,o.yg)("inlineCode",{parentName:"p"},"fifo")," (default)"),(0,o.yg)("p",null,"Before sorting, the applications are filtered and must have pending resource requests."),(0,o.yg)("p",null,"After filtering the applications left are sorted based on the application create time stamp only, no other filtering is applied.\nSince applications can only be added while the system is locked there can never be two applications with the exact same time stamp. "),(0,o.yg)("p",null,"The result is that the oldest application that requests resources gets resources.\nYounger applications will be given resources when all the current requests of older applications have been fulfilled. "),(0,o.yg)("h3",{id:"fairsortpolicy"},"FairSortPolicy"),(0,o.yg)("p",null,"Short description: fair based on usage "),(0,o.yg)("p",null,"Config value: ",(0,o.yg)("inlineCode",{parentName:"p"},"fair")),(0,o.yg)("p",null,"Before sorting the applications are filtered and must have pending resource requests."),(0,o.yg)("p",null,"After filtering the applications left are sorted based on the application usage.\nThe usage of the application is defined as all confirmed and unconfirmed allocations for the applications.\nAll resources defined on the application will be taken into account when calculating the usage."),(0,o.yg)("p",null,"The result is that the resources available are spread equally over all applications that request resources."),(0,o.yg)("h2",{id:"node-sorting"},"Node sorting"),(0,o.yg)("p",null,"The node sorting policy is set for a partition via the config.\nEach partition can use a different policy."),(0,o.yg)("p",null,"The following configuration entry sets the node sorting policy to ",(0,o.yg)("inlineCode",{parentName:"p"},"fair")," for the partition ",(0,o.yg)("inlineCode",{parentName:"p"},"default"),": "),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n nodesortpolicy:\n type: fair\n")),(0,o.yg)("h3",{id:"fairnesspolicy"},"FairnessPolicy"),(0,o.yg)("p",null,"Short description: available resource, descending order",(0,o.yg)("br",{parentName:"p"}),"\n","Config value: fair (default)",(0,o.yg)("br",{parentName:"p"}),"\n","Behaviour:",(0,o.yg)("br",{parentName:"p"}),"\n","Sort the list of nodes by the amount of available resources so that the node with the ",(0,o.yg)("em",{parentName:"p"},"highest")," amount of available resource is the first in the list.\nAll resources defined on a node will be taken into account when calculating the usage.\nResources of the same type are compared for the nodes. "),(0,o.yg)("p",null,"This results in a node with the lowest utilisation to be considered first for assigning new allocation.\nResulting in a spread of allocations over all available nodes.\nLeading to an overall lower utilisation of the individual available nodes, unless the whole environment is highly utilised.\nKeeping the load on all nodes at a similar level does help\nIn an environment that auto scales by adding new nodes this could trigger unexpected auto scale requests. "),(0,o.yg)("h3",{id:"binpackingpolicy"},"BinPackingPolicy"),(0,o.yg)("p",null,"Short description: available resource, ascending order",(0,o.yg)("br",{parentName:"p"}),"\n","Config value: binpacking",(0,o.yg)("br",{parentName:"p"}),"\n","Behaviour:",(0,o.yg)("br",{parentName:"p"}),"\n","Sort the list of nodes by the amount of available resources so that the node with the ",(0,o.yg)("em",{parentName:"p"},"lowest")," amount of available resource is the first in the list.\nAll resources defined on a node will be taken into account when calculating the usage.\nResources of the same type are compared for the nodes. "),(0,o.yg)("p",null,"This results in a node with the highest utilisation to be considered first for assigning new allocation.\nResulting in a high(er) utilisation of a small(er) number of nodes, better suited for cloud deployments. "),(0,o.yg)("h2",{id:"resource-weighting"},"Resource weighting"),(0,o.yg)("p",null,"Node sorting policies may use the utilization of a node to determine ordering. Because nodes can have several unique\nresource types, a node's utilization is determined by a weighted average of its individual resource types. Resource\nweighting can be customized by using the ",(0,o.yg)("inlineCode",{parentName:"p"},"resourceweights")," section of ",(0,o.yg)("inlineCode",{parentName:"p"},"nodesortpolicy"),". If ",(0,o.yg)("inlineCode",{parentName:"p"},"resourceweights")," is not\npresent or empty, the default configuration sets the weight of both ",(0,o.yg)("inlineCode",{parentName:"p"},"vcore")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"memory")," equally to ",(0,o.yg)("inlineCode",{parentName:"p"},"1.0"),". All other\nresource types are ignored. Only resource types explicitly mentioned will have a weight."),(0,o.yg)("p",null,"YuniKorn tracks CPU resources internally as the ",(0,o.yg)("inlineCode",{parentName:"p"},"vcore")," resource type. This maps to the Kubernetes resource type ",(0,o.yg)("inlineCode",{parentName:"p"},"cpu"),".\nAll other resource types have consistent naming between YuniKorn and Kubernetes."),(0,o.yg)("p",null,"For example, in the default configuration, if a node has ",(0,o.yg)("inlineCode",{parentName:"p"},"90%")," of its CPU and ",(0,o.yg)("inlineCode",{parentName:"p"},"50%")," of its memory allocated, the node\nwill be considered to be ",(0,o.yg)("inlineCode",{parentName:"p"},"70%")," utilized."),(0,o.yg)("p",null,"The following configuration entry sets the weight of ",(0,o.yg)("inlineCode",{parentName:"p"},"vcore")," to ",(0,o.yg)("inlineCode",{parentName:"p"},"4.0")," and ",(0,o.yg)("inlineCode",{parentName:"p"},"memory")," to ",(0,o.yg)("inlineCode",{parentName:"p"},"1.0")," for the partition ",(0,o.yg)("inlineCode",{parentName:"p"},"default"),".\nThis will weight CPU usage four times higher than memory usage:"),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n nodesortpolicy:\n type: fair\n resourceweights:\n vcore: 4.0\n memory: 1.0\n")),(0,o.yg)("p",null,"With this configuration, In this example, if a node has ",(0,o.yg)("inlineCode",{parentName:"p"},"90%")," of its CPU and ",(0,o.yg)("inlineCode",{parentName:"p"},"50%")," of its memory allocated, the node\nwill be considered to be ",(0,o.yg)("inlineCode",{parentName:"p"},"82%")," utilized."),(0,o.yg)("p",null,"Note that weights are relative to each other, so specifying weights of ",(0,o.yg)("inlineCode",{parentName:"p"},"{ 4.0, 1.0 }")," is equivalent to\n",(0,o.yg)("inlineCode",{parentName:"p"},"{ 1.0, 0.25 }"),". Negative weights are not allowed."),(0,o.yg)("h2",{id:"request-sorting"},"Request sorting"),(0,o.yg)("p",null,"There is currently one policy for sorting requests within an application.\nThis policy is not configurable.\nSorting requests is only possible based on the priority of the request.\nIf there are multiple requests within an application that have the same priority the order of the requests is undetermined.\nThis means that the order of requests with the same priority can, and most likely will, change between runs."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/afe6f65e.c96f522e.js b/assets/js/afe6f65e.c96f522e.js deleted file mode 100644 index 3d7cf3376bf..00000000000 --- a/assets/js/afe6f65e.c96f522e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[35173],{58860:(e,t,n)=>{n.d(t,{xA:()=>u,yg:()=>h});var i=n(37953);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),p=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return i.createElement(s.Provider,{value:t},e.children)},c="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=a,h=c["".concat(s,".").concat(d)]||c[d]||g[d]||r;return n?i.createElement(h,o(o({ref:t},u),{},{components:n})):i.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>g,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var i=n(72994),a=(n(37953),n(58860));const r={id:"sorting_policies",title:"Sorting Policies"},o=void 0,l={unversionedId:"user_guide/sorting_policies",id:"user_guide/sorting_policies",title:"Sorting Policies",description:"\x3c!--",source:"@site/docs/user_guide/sorting_policies.md",sourceDirName:"user_guide",slug:"/user_guide/sorting_policies",permalink:"/docs/next/user_guide/sorting_policies",draft:!1,tags:[],version:"current",frontMatter:{id:"sorting_policies",title:"Sorting Policies"},sidebar:"docs",previous:{title:"User & Group Resolution",permalink:"/docs/next/user_guide/usergroup_resolution"},next:{title:"App & Queue Priorities",permalink:"/docs/next/user_guide/priorities"}},s={},p=[{value:"Application sorting",id:"application-sorting",level:2},{value:"FifoSortPolicy",id:"fifosortpolicy",level:3},{value:"FairSortPolicy",id:"fairsortpolicy",level:3},{value:"StateAwarePolicy",id:"stateawarepolicy",level:3},{value:"Node sorting",id:"node-sorting",level:2},{value:"FairnessPolicy",id:"fairnesspolicy",level:3},{value:"BinPackingPolicy",id:"binpackingpolicy",level:3},{value:"Resource weighting",id:"resource-weighting",level:2},{value:"Request sorting",id:"request-sorting",level:2}],u={toc:p},c="wrapper";function g(e){let{components:t,...n}=e;return(0,a.yg)(c,(0,i.A)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"The scheduler uses policies allow changing the scheduling behaviour without code changes.\nPolicies can be set for:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"#application-sorting"},"Applications")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"#node-sorting"},"Nodes")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("a",{parentName:"li",href:"#request-sorting"},"Requests"))),(0,a.yg)("h2",{id:"application-sorting"},"Application sorting"),(0,a.yg)("p",null,"The application sorting policy is set for each queue via the config.\nA sorting policy setting is only effective on a ",(0,a.yg)("em",{parentName:"p"},"leaf")," queue.\nEach ",(0,a.yg)("em",{parentName:"p"},"leaf")," queue can use a different policy."),(0,a.yg)("p",null,"A sorting policy only specifies the order in which the applications are sorted within a queue.\nThat order is crucial in specifying which application is considered first when assigning resources.\nSorting policies do ",(0,a.yg)("em",{parentName:"p"},"not")," affect the number of applications that are scheduled or active in the queue at the same time.\nAll applications that have pending resource requests can and will be scheduled in a queue unless specifically filtered out.\nEven when applications are sorted using a first in first out policy multiple applications will run in a queue in parallel. "),(0,a.yg)("p",null,"A ",(0,a.yg)("em",{parentName:"p"},"parent")," queue will always use the fair policy to sort the child queues."),(0,a.yg)("p",null,"The relative priority of child queues (in the case of ",(0,a.yg)("em",{parentName:"p"},"parent")," queue sorting)\nand applications (in the case of ",(0,a.yg)("em",{parentName:"p"},"leaf")," queue sorting) will be considered first.\nTo ignore application and queue priorities when scheduling, set the queue\nproperty ",(0,a.yg)("inlineCode",{parentName:"p"},"application.sort.priority")," to ",(0,a.yg)("inlineCode",{parentName:"p"},"disabled"),"."),(0,a.yg)("p",null,"The following configuration entry sets the application sorting policy to ",(0,a.yg)("inlineCode",{parentName:"p"},"fifo")," for the queue ",(0,a.yg)("inlineCode",{parentName:"p"},"root.sandbox"),": "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n queues:\n - name: root\n queues:\n - name: sandbox\n properties:\n application.sort.policy: fifo\n")),(0,a.yg)("p",null,"The only applications that are considered during scheduling must have outstanding requests.\nA filter is applied ",(0,a.yg)("em",{parentName:"p"},"while")," sorting the applications to remove all that do not have outstanding requests."),(0,a.yg)("h3",{id:"fifosortpolicy"},"FifoSortPolicy"),(0,a.yg)("p",null,"Short description: first in first out, based on application create time "),(0,a.yg)("p",null,"Config value: ",(0,a.yg)("inlineCode",{parentName:"p"},"fifo")," (default)"),(0,a.yg)("p",null,"Before sorting, the applications are filtered and must have pending resource requests."),(0,a.yg)("p",null,"After filtering the applications left are sorted based on the application create time stamp only, no other filtering is applied.\nSince applications can only be added while the system is locked there can never be two applications with the exact same time stamp. "),(0,a.yg)("p",null,"The result is that the oldest application that requests resources gets resources.\nYounger applications will be given resources when all the current requests of older applications have been fulfilled. "),(0,a.yg)("h3",{id:"fairsortpolicy"},"FairSortPolicy"),(0,a.yg)("p",null,"Short description: fair based on usage "),(0,a.yg)("p",null,"Config value: ",(0,a.yg)("inlineCode",{parentName:"p"},"fair")),(0,a.yg)("p",null,"Before sorting the applications are filtered and must have pending resource requests."),(0,a.yg)("p",null,"After filtering the applications left are sorted based on the application usage.\nThe usage of the application is defined as all confirmed and unconfirmed allocations for the applications.\nAll resources defined on the application will be taken into account when calculating the usage."),(0,a.yg)("p",null,"The result is that the resources available are spread equally over all applications that request resources."),(0,a.yg)("h3",{id:"stateawarepolicy"},"StateAwarePolicy"),(0,a.yg)("p",null,"Short description: limit of one (1) application in Starting or Accepted state "),(0,a.yg)("p",null,"Config value: ",(0,a.yg)("inlineCode",{parentName:"p"},"stateaware")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"DEPRECATED:")," The ",(0,a.yg)("inlineCode",{parentName:"p"},"stateaware")," policy is ",(0,a.yg)("strong",{parentName:"p"},"deprecated")," in YuniKorn 1.5.0 and\nwill be ",(0,a.yg)("strong",{parentName:"p"},"removed")," in YuniKorn 1.6.0. To preserve backwards compatibility,\n",(0,a.yg)("inlineCode",{parentName:"p"},"stateaware")," will become an alias for ",(0,a.yg)("inlineCode",{parentName:"p"},"fifo")," in YuniKorn 1.6.0 and later.\nUsers are encouraged to migrate to ",(0,a.yg)("inlineCode",{parentName:"p"},"fifo")," and utilize either gang scheduling or\n",(0,a.yg)("inlineCode",{parentName:"p"},"maxapplications")," to limit concurrency instead."),(0,a.yg)("p",null,"This sorting policy requires an understanding of the application states.\nApplications states are described in the ",(0,a.yg)("a",{parentName:"p",href:"/docs/next/developer_guide/scheduler_object_states#application-state"},"application states")," documentation."),(0,a.yg)("p",null,"Before sorting applications the following filters are applied to all applications in the queue:\nThe first filter is based on the application state.\nThe following applications pass through the filter and generate the first intermediate list:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"all applications in the state ",(0,a.yg)("em",{parentName:"li"},"running")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("em",{parentName:"li"},"one")," (1) application in the ",(0,a.yg)("em",{parentName:"li"},"starting")," state"),(0,a.yg)("li",{parentName:"ul"},"if there are ",(0,a.yg)("em",{parentName:"li"},"no")," applications in the ",(0,a.yg)("em",{parentName:"li"},"starting")," state ",(0,a.yg)("em",{parentName:"li"},"one")," (1) application in the ",(0,a.yg)("em",{parentName:"li"},"accepted")," state is added")),(0,a.yg)("p",null,"The second filter takes the result of the first filter as an input.\nThe preliminary list is filtered again: all applications ",(0,a.yg)("em",{parentName:"p"},"without")," a pending request are removed."),(0,a.yg)("p",null,"After filtering based on status and pending requests the applications that remain are sorted.\nThe final list is thus filtered twice with the remaining applications sorted on create time."),(0,a.yg)("p",null,"To recap the ",(0,a.yg)("em",{parentName:"p"},"staring")," and ",(0,a.yg)("em",{parentName:"p"},"accepted")," state interactions:\nThe application in the ",(0,a.yg)("em",{parentName:"p"},"accepted")," state is only added if there is no application in the ",(0,a.yg)("em",{parentName:"p"},"starting")," state.\nThe application in the ",(0,a.yg)("em",{parentName:"p"},"starting")," state does not have to have pending requests.\nAny application in the ",(0,a.yg)("em",{parentName:"p"},"starting")," state will prevent ",(0,a.yg)("em",{parentName:"p"},"accepted")," applications from being added to the filtered list."),(0,a.yg)("p",null,"For further details see the ",(0,a.yg)("a",{parentName:"p",href:"/docs/next/design/state_aware_scheduling#example-run"},"Example run")," in the design document."),(0,a.yg)("p",null,"The result is that already running applications that request resources will get resources first.\nA drip feed of one new applications is added to the list of running applications to be allocated after all running applications. "),(0,a.yg)("h2",{id:"node-sorting"},"Node sorting"),(0,a.yg)("p",null,"The node sorting policy is set for a partition via the config.\nEach partition can use a different policy."),(0,a.yg)("p",null,"The following configuration entry sets the node sorting policy to ",(0,a.yg)("inlineCode",{parentName:"p"},"fair")," for the partition ",(0,a.yg)("inlineCode",{parentName:"p"},"default"),": "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n nodesortpolicy:\n type: fair\n")),(0,a.yg)("h3",{id:"fairnesspolicy"},"FairnessPolicy"),(0,a.yg)("p",null,"Short description: available resource, descending order",(0,a.yg)("br",{parentName:"p"}),"\n","Config value: fair (default)",(0,a.yg)("br",{parentName:"p"}),"\n","Behaviour:",(0,a.yg)("br",{parentName:"p"}),"\n","Sort the list of nodes by the amount of available resources so that the node with the ",(0,a.yg)("em",{parentName:"p"},"highest")," amount of available resource is the first in the list.\nAll resources defined on a node will be taken into account when calculating the usage.\nResources of the same type are compared for the nodes. "),(0,a.yg)("p",null,"This results in a node with the lowest utilisation to be considered first for assigning new allocation.\nResulting in a spread of allocations over all available nodes.\nLeading to an overall lower utilisation of the individual available nodes, unless the whole environment is highly utilised.\nKeeping the load on all nodes at a similar level does help\nIn an environment that auto scales by adding new nodes this could trigger unexpected auto scale requests. "),(0,a.yg)("h3",{id:"binpackingpolicy"},"BinPackingPolicy"),(0,a.yg)("p",null,"Short description: available resource, ascending order",(0,a.yg)("br",{parentName:"p"}),"\n","Config value: binpacking",(0,a.yg)("br",{parentName:"p"}),"\n","Behaviour:",(0,a.yg)("br",{parentName:"p"}),"\n","Sort the list of nodes by the amount of available resources so that the node with the ",(0,a.yg)("em",{parentName:"p"},"lowest")," amount of available resource is the first in the list.\nAll resources defined on a node will be taken into account when calculating the usage.\nResources of the same type are compared for the nodes. "),(0,a.yg)("p",null,"This results in a node with the highest utilisation to be considered first for assigning new allocation.\nResulting in a high(er) utilisation of a small(er) number of nodes, better suited for cloud deployments. "),(0,a.yg)("h2",{id:"resource-weighting"},"Resource weighting"),(0,a.yg)("p",null,"Node sorting policies may use the utilization of a node to determine ordering. Because nodes can have several unique\nresource types, a node's utilization is determined by a weighted average of its individual resource types. Resource\nweighting can be customized by using the ",(0,a.yg)("inlineCode",{parentName:"p"},"resourceweights")," section of ",(0,a.yg)("inlineCode",{parentName:"p"},"nodesortpolicy"),". If ",(0,a.yg)("inlineCode",{parentName:"p"},"resourceweights")," is not\npresent or empty, the default configuration sets the weight of both ",(0,a.yg)("inlineCode",{parentName:"p"},"vcore")," and ",(0,a.yg)("inlineCode",{parentName:"p"},"memory")," equally to ",(0,a.yg)("inlineCode",{parentName:"p"},"1.0"),". All other\nresource types are ignored. Only resource types explicitly mentioned will have a weight."),(0,a.yg)("p",null,"YuniKorn tracks CPU resources internally as the ",(0,a.yg)("inlineCode",{parentName:"p"},"vcore")," resource type. This maps to the Kubernetes resource type ",(0,a.yg)("inlineCode",{parentName:"p"},"cpu"),".\nAll other resource types have consistent naming between YuniKorn and Kubernetes."),(0,a.yg)("p",null,"For example, in the default configuration, if a node has ",(0,a.yg)("inlineCode",{parentName:"p"},"90%")," of its CPU and ",(0,a.yg)("inlineCode",{parentName:"p"},"50%")," of its memory allocated, the node\nwill be considered to be ",(0,a.yg)("inlineCode",{parentName:"p"},"70%")," utilized."),(0,a.yg)("p",null,"The following configuration entry sets the weight of ",(0,a.yg)("inlineCode",{parentName:"p"},"vcore")," to ",(0,a.yg)("inlineCode",{parentName:"p"},"4.0")," and ",(0,a.yg)("inlineCode",{parentName:"p"},"memory")," to ",(0,a.yg)("inlineCode",{parentName:"p"},"1.0")," for the partition ",(0,a.yg)("inlineCode",{parentName:"p"},"default"),".\nThis will weight CPU usage four times higher than memory usage:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"partitions:\n - name: default\n nodesortpolicy:\n type: fair\n resourceweights:\n vcore: 4.0\n memory: 1.0\n")),(0,a.yg)("p",null,"With this configuration, In this example, if a node has ",(0,a.yg)("inlineCode",{parentName:"p"},"90%")," of its CPU and ",(0,a.yg)("inlineCode",{parentName:"p"},"50%")," of its memory allocated, the node\nwill be considered to be ",(0,a.yg)("inlineCode",{parentName:"p"},"82%")," utilized."),(0,a.yg)("p",null,"Note that weights are relative to each other, so specifying weights of ",(0,a.yg)("inlineCode",{parentName:"p"},"{ 4.0, 1.0 }")," is equivalent to\n",(0,a.yg)("inlineCode",{parentName:"p"},"{ 1.0, 0.25 }"),". Negative weights are not allowed."),(0,a.yg)("h2",{id:"request-sorting"},"Request sorting"),(0,a.yg)("p",null,"There is currently one policy for sorting requests within an application.\nThis policy is not configurable.\nSorting requests is only possible based on the priority of the request.\nIf there are multiple requests within an application that have the same priority the order of the requests is undetermined.\nThis means that the order of requests with the same priority can, and most likely will, change between runs."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c78cff6c.b12cdc7a.js b/assets/js/c78cff6c.b12cdc7a.js new file mode 100644 index 00000000000..03d4a9c28e9 --- /dev/null +++ b/assets/js/c78cff6c.b12cdc7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[46067],{58860:(e,t,n)=>{n.d(t,{xA:()=>c,yg:()=>g});var o=n(37953);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),s=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return o.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(n),m=r,g=d["".concat(l,".").concat(m)]||d[m]||u[m]||a;return n?o.createElement(g,i(i({ref:t},c),{},{components:n})):o.createElement(g,i({ref:t},c))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p[d]="string"==typeof e?e:r,i[1]=p;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var o=n(72994),r=(n(37953),n(58860));const a={id:"cross_queue_preemption",title:"Cross Queue Preemption"},i=void 0,p={unversionedId:"archived_design/cross_queue_preemption",id:"archived_design/cross_queue_preemption",title:"Cross Queue Preemption",description:"\x3c!--",source:"@site/docs/archived_design/cross_queue_preemption.md",sourceDirName:"archived_design",slug:"/archived_design/cross_queue_preemption",permalink:"/docs/next/archived_design/cross_queue_preemption",draft:!1,tags:[],version:"current",frontMatter:{id:"cross_queue_preemption",title:"Cross Queue Preemption"},sidebar:"docs",previous:{title:"Batch Workloads Ordering with StateAware Policy",permalink:"/docs/next/archived_design/state_aware_scheduling"},next:{title:"Pluggable App Management",permalink:"/docs/next/archived_design/pluggable_app_management"}},l={},s=[{value:"Problems:",id:"problems",level:2},{value:"Answer some questions for design/implementation choices",id:"answer-some-questions-for-designimplementation-choices",level:2},{value:"Pseudo code",id:"pseudo-code",level:2}],c={toc:s},d="wrapper";function u(e){let{components:t,...n}=e;return(0,r.yg)(d,(0,o.A)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.yg)("h2",{id:"problems"},"Problems:"),(0,r.yg)("p",null,"According to lessons we learned from YARN Scheduler preemption. "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Here're top bad things:")," "),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Preemption is a shotgun instead of a sniper, when a preemption decision is made, nobody knows if preempted resources will go to demanding queue/app/user or not."),(0,r.yg)("li",{parentName:"ul"},"Preemption logic and allocation is different, we have to implement (and mimic) what we have done in scheduler allocation logic. ")),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Here're top good things:")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Preemption is fast (thanks to the shotgun), reclaiming thousands of containers only takes ~ 1 sec. "),(0,r.yg)("li",{parentName:"ul"},"We have understand how painful it is to handle DRF, multiple preemption policies (inter/intra-queue, shotgun/surgical preemption, etc.) And we have developed some good logic\nto make sure better modularization and plug-ability ")),(0,r.yg)("h2",{id:"answer-some-questions-for-designimplementation-choices"},"Answer some questions for design/implementation choices"),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"1","."," Do we really want preemption-delay? (Or we just want to control pace)")),(0,r.yg)("p",null,"In CS, we have preemption-delay, which select victims in preemption candidates, wait for a certain time before killing it. "),(0,r.yg)("p",null,"The purposes of preemption delay are: a. give heads-up time to apps so\nthey can prepare bad things happen (unfortunately no app do anything for these heads up, at least from what I knew). b. control preemption pace. "),(0,r.yg)("p",null,"And in practice, I found it causes a lot of issues, for example when a\ncluster state keep changing, it is very hard to ensure accurate preemption. "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Proposal:")),(0,r.yg)("p",null,"Remove the preemption-delay, keep the logics of controlling preemption pace. (such as ",(0,r.yg)("inlineCode",{parentName:"p"},"yarn.resourcemanager.monitor.capacity.preemption\n.total_preemption_per_round"),"). And we can do allocation together with preemption.\nThis don't mean containers will be stopped immediately after preemption issued. Instead, RM can control delays between signal a container and kill a container. Such as grace\ntermination of POD in K8s: ",(0,r.yg)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods"},"https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods")," "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"2","."," Do we want to do preemption for every scheduling logic, or we can do periodically?")),(0,r.yg)("p",null,"In CS, we have preemption logic runs periodically, like every 1 sec or 3 sec. "),(0,r.yg)("p",null,"Since preemption logic involves some heavy logics, like calculating shares of queues/apps. And when doing accurate preemption, we may need to scan nodes for preemption candidate.\nConsidering this, I propose to have preemption runs periodically. But it is important to note that, we need to try to use as much code as possible for\nallocation-inside-preemption, otherwise there will be too much duplicated logic and very hard to be maintained in the future."),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"3","."," Preemption cost and function")),(0,r.yg)("p",null,"We found it is helpful to add cost for preemption, such as container live time, priority, type of container. It could be a cost function (Which returns a numeric value) or it\ncould be a comparator (which compare two allocations for preemption ask)."),(0,r.yg)("h2",{id:"pseudo-code"},"Pseudo code"),(0,r.yg)("p",null,"Logic of allocation (invoked every allocation cycle)"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"input:\n - nAlloc, allocate N allocations for this allocation cycle.\n\nfor partition: \n askCandidates := findAskCandidates(nAlloc, preemption=false)\n \n allocated, failed_to_allocated := tryAllocate(askCandidates);\n \n send-allocated-to-cache-to-commit;\n \n update-missed-opportunity (allocated, failed_to_allocated);\n \n nAlloc -= len(allocated) \n")),(0,r.yg)("p",null,"Logic of preemption (invoked every preemption cycle)"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"// It has to be done for every preemption-policy because calculation is different.\nfor preemption-policy: \n preempt_results := policy.preempt()\n for preempt_results: \n send-preempt-result-to-cache-to-commit;\n updated-missed-opportunity (allocated)\n")),(0,r.yg)("p",null,"Inside preemption policy"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"inter-queue-preempt-policy:\n calculate-preemption-quotas;\n \n for partitions:\n total_preempted := resource(0);\n \n while total_preempted < partition-limited:\n // queues will be sorted by allocating - preempting\n // And ignore any key in preemption_mask\n askCandidates := findAskCandidates(N, preemption=true)\n \n preempt_results := tryAllocate(askCandidates, preemption=true);\n \n total_preempted += sigma(preempt_result.allocResource)\n \n send-allocated-to-cache-to-commit;\n \n update-missed-opportunity (allocated, failed_to_allocated);\n \n update-preemption-mask(askCandidates.allocKeys - preempt_results.allocKeys)\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c78cff6c.cd939cca.js b/assets/js/c78cff6c.cd939cca.js deleted file mode 100644 index d364e44834c..00000000000 --- a/assets/js/c78cff6c.cd939cca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[46067],{58860:(e,n,t)=>{t.d(n,{xA:()=>c,yg:()=>g});var o=t(37953);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=o.createContext({}),s=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=s(e.components);return o.createElement(l.Provider,{value:n},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},m=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=s(t),m=r,g=d["".concat(l,".").concat(m)]||d[m]||u[m]||i;return t?o.createElement(g,a(a({ref:n},c),{},{components:t})):o.createElement(g,a({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var i=t.length,a=new Array(i);a[0]=m;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p[d]="string"==typeof e?e:r,a[1]=p;for(var s=2;s{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>s});var o=t(72994),r=(t(37953),t(58860));const i={id:"cross_queue_preemption",title:"Cross Queue Preemption"},a=void 0,p={unversionedId:"archived_design/cross_queue_preemption",id:"archived_design/cross_queue_preemption",title:"Cross Queue Preemption",description:"\x3c!--",source:"@site/docs/archived_design/cross_queue_preemption.md",sourceDirName:"archived_design",slug:"/archived_design/cross_queue_preemption",permalink:"/docs/next/archived_design/cross_queue_preemption",draft:!1,tags:[],version:"current",frontMatter:{id:"cross_queue_preemption",title:"Cross Queue Preemption"},sidebar:"docs",previous:{title:"Scheduler Core Design",permalink:"/docs/next/archived_design/scheduler_core_design"},next:{title:"Pluggable App Management",permalink:"/docs/next/archived_design/pluggable_app_management"}},l={},s=[{value:"Problems:",id:"problems",level:2},{value:"Answer some questions for design/implementation choices",id:"answer-some-questions-for-designimplementation-choices",level:2},{value:"Pseudo code",id:"pseudo-code",level:2}],c={toc:s},d="wrapper";function u(e){let{components:n,...t}=e;return(0,r.yg)(d,(0,o.A)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.yg)("h2",{id:"problems"},"Problems:"),(0,r.yg)("p",null,"According to lessons we learned from YARN Scheduler preemption. "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Here're top bad things:")," "),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Preemption is a shotgun instead of a sniper, when a preemption decision is made, nobody knows if preempted resources will go to demanding queue/app/user or not."),(0,r.yg)("li",{parentName:"ul"},"Preemption logic and allocation is different, we have to implement (and mimic) what we have done in scheduler allocation logic. ")),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Here're top good things:")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Preemption is fast (thanks to the shotgun), reclaiming thousands of containers only takes ~ 1 sec. "),(0,r.yg)("li",{parentName:"ul"},"We have understand how painful it is to handle DRF, multiple preemption policies (inter/intra-queue, shotgun/surgical preemption, etc.) And we have developed some good logic\nto make sure better modularization and plug-ability ")),(0,r.yg)("h2",{id:"answer-some-questions-for-designimplementation-choices"},"Answer some questions for design/implementation choices"),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"1","."," Do we really want preemption-delay? (Or we just want to control pace)")),(0,r.yg)("p",null,"In CS, we have preemption-delay, which select victims in preemption candidates, wait for a certain time before killing it. "),(0,r.yg)("p",null,"The purposes of preemption delay are: a. give heads-up time to apps so\nthey can prepare bad things happen (unfortunately no app do anything for these heads up, at least from what I knew). b. control preemption pace. "),(0,r.yg)("p",null,"And in practice, I found it causes a lot of issues, for example when a\ncluster state keep changing, it is very hard to ensure accurate preemption. "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Proposal:")),(0,r.yg)("p",null,"Remove the preemption-delay, keep the logics of controlling preemption pace. (such as ",(0,r.yg)("inlineCode",{parentName:"p"},"yarn.resourcemanager.monitor.capacity.preemption\n.total_preemption_per_round"),"). And we can do allocation together with preemption.\nThis don't mean containers will be stopped immediately after preemption issued. Instead, RM can control delays between signal a container and kill a container. Such as grace\ntermination of POD in K8s: ",(0,r.yg)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods"},"https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods")," "),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"2","."," Do we want to do preemption for every scheduling logic, or we can do periodically?")),(0,r.yg)("p",null,"In CS, we have preemption logic runs periodically, like every 1 sec or 3 sec. "),(0,r.yg)("p",null,"Since preemption logic involves some heavy logics, like calculating shares of queues/apps. And when doing accurate preemption, we may need to scan nodes for preemption candidate.\nConsidering this, I propose to have preemption runs periodically. But it is important to note that, we need to try to use as much code as possible for\nallocation-inside-preemption, otherwise there will be too much duplicated logic and very hard to be maintained in the future."),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"3","."," Preemption cost and function")),(0,r.yg)("p",null,"We found it is helpful to add cost for preemption, such as container live time, priority, type of container. It could be a cost function (Which returns a numeric value) or it\ncould be a comparator (which compare two allocations for preemption ask)."),(0,r.yg)("h2",{id:"pseudo-code"},"Pseudo code"),(0,r.yg)("p",null,"Logic of allocation (invoked every allocation cycle)"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"input:\n - nAlloc, allocate N allocations for this allocation cycle.\n\nfor partition: \n askCandidates := findAskCandidates(nAlloc, preemption=false)\n \n allocated, failed_to_allocated := tryAllocate(askCandidates);\n \n send-allocated-to-cache-to-commit;\n \n update-missed-opportunity (allocated, failed_to_allocated);\n \n nAlloc -= len(allocated) \n")),(0,r.yg)("p",null,"Logic of preemption (invoked every preemption cycle)"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"// It has to be done for every preemption-policy because calculation is different.\nfor preemption-policy: \n preempt_results := policy.preempt()\n for preempt_results: \n send-preempt-result-to-cache-to-commit;\n updated-missed-opportunity (allocated)\n")),(0,r.yg)("p",null,"Inside preemption policy"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"inter-queue-preempt-policy:\n calculate-preemption-quotas;\n \n for partitions:\n total_preempted := resource(0);\n \n while total_preempted < partition-limited:\n // queues will be sorted by allocating - preempting\n // And ignore any key in preemption_mask\n askCandidates := findAskCandidates(N, preemption=true)\n \n preempt_results := tryAllocate(askCandidates, preemption=true);\n \n total_preempted += sigma(preempt_result.allocResource)\n \n send-allocated-to-cache-to-commit;\n \n update-missed-opportunity (allocated, failed_to_allocated);\n \n update-preemption-mask(askCandidates.allocKeys - preempt_results.allocKeys)\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f82ec024.7b3a43e0.js b/assets/js/f82ec024.7b3a43e0.js new file mode 100644 index 00000000000..a35f27b56bb --- /dev/null +++ b/assets/js/f82ec024.7b3a43e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[32477],{58860:(e,t,a)=>{a.d(t,{xA:()=>h,yg:()=>g});var i=a(37953);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),c=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},h=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,h=r(e,["components","mdxType","originalType","parentName"]),p=c(a),d=n,g=p["".concat(l,".").concat(d)]||p[d]||u[d]||s;return a?i.createElement(g,o(o({ref:t},h),{},{components:a})):i.createElement(g,o({ref:t},h))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[p]="string"==typeof e?e:n,o[1]=r;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=a(72994),n=(a(37953),a(58860));const s={id:"state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy"},o=void 0,r={unversionedId:"archived_design/state_aware_scheduling",id:"archived_design/state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy",description:"\x3c!--",source:"@site/docs/archived_design/state_aware_scheduling.md",sourceDirName:"archived_design",slug:"/archived_design/state_aware_scheduling",permalink:"/docs/next/archived_design/state_aware_scheduling",draft:!1,tags:[],version:"current",frontMatter:{id:"state_aware_scheduling",title:"Batch Workloads Ordering with StateAware Policy"},sidebar:"docs",previous:{title:"Scheduler Core Design",permalink:"/docs/next/archived_design/scheduler_core_design"},next:{title:"Cross Queue Preemption",permalink:"/docs/next/archived_design/cross_queue_preemption"}},l={},c=[{value:"The problem",id:"the-problem",level:2},{value:"Example issue",id:"example-issue",level:3},{value:"Design",id:"design",level:2},{value:"Design goals",id:"design-goals",level:3},{value:"None goals",id:"none-goals",level:3},{value:"Possible solutions",id:"possible-solutions",level:3},{value:"Algorithm",id:"algorithm",level:3},{value:"Fallback mechanism",id:"fallback-mechanism",level:3},{value:"Example run",id:"example-run",level:3}],h={toc:c},p="wrapper";function u(e){let{components:t,...s}=e;return(0,n.yg)(p,(0,i.A)({},h,s,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"the-problem"},"The problem"),(0,n.yg)("p",null,"A common pattern while processing data is that the application can be divided into multiple stages.\nAnother way to look at this is the fact that processing needs to be kicked off and that the first step is to start a driver or manager for the application.\nLater stages might depend on the previous stages.\nWhen running applications in a size limited environment this could lead to a resource exhaustion when submitting multiple applications at the same time.\nThese first stages might consume all available resources leaving no room for the next stage(s) to start.\nOften this issue is caused by having a high number of applications start simultaneous and trying to get resources in parallel."),(0,n.yg)("h3",{id:"example-issue"},"Example issue"),(0,n.yg)("p",null,"When submitting numerous Spark applications in a short amount of time the drivers will all be started shortly after each other.\nThe drivers consume all available resources in a queue or in the whole cluster.\nAfter starting the drivers they will request resources for the executors.\nSince the queue or cluster has no resources left the executors will not be started.\nThe driver cannot progress.\nThe only way that progress would be made is if and when one of the drivers finishes or fails and frees up resources for executors to be started."),(0,n.yg)("h2",{id:"design"},"Design"),(0,n.yg)("h3",{id:"design-goals"},"Design goals"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"Prevent resource exhaustion by first stage allocations"),(0,n.yg)("li",{parentName:"ol"},"Improve chance for jobs to get minimal required resources over others")),(0,n.yg)("h3",{id:"none-goals"},"None goals"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"This is NOT an implementation of Gang scheduling."),(0,n.yg)("li",{parentName:"ol"},"No change to the currently supported FAIR or FIFO scheduling algorithms"),(0,n.yg)("li",{parentName:"ol"},"Fix resource quota usage outside of the core scheduler for submitted but waiting applications")),(0,n.yg)("h3",{id:"possible-solutions"},"Possible solutions"),(0,n.yg)("p",null,"Other batch schedulers like the YARN schedulers use a limit on the number of simultaneous running applications.\nThey use either resource constraints on the driver or management stage or set a hard limit of the number of applications that can run in a queue.\nThe draw back of that solution is that it does not work well in a cluster that can scale up or down automatically in a cloud environment.\nTo work around that percentage based limits could be set on the consumed resources for the driver or management stage.\nThis does not alleviate the fact that driver or management stages can be of any size, large and or small, which complicates the percentage scenario further as it does not give a predictable behaviour."),(0,n.yg)("p",null,"A different solution would be to assume a specific behaviour of the applications.\nUsing that assumption a limit on the applications could be set based on the state it is in.\nThe spark driver and executor behaviour is the most usual use case.\nThis would provide a way to limit scheduling to existing applications and only drip feed new applications into the list of applications to schedule when there are resources available."),(0,n.yg)("h3",{id:"algorithm"},"Algorithm"),(0,n.yg)("p",null,"The algorithm described here is based on the drip feed of new applications into the applications to schedule based on the states of all applications.\nScheduling is based on the applications in a queue.\nThe algorithm will be applied at a queue level.\nThis is not a cluster wide setup."),(0,n.yg)("p",null,"What we want to achieve is the following behaviour: only schedule one (1) application that is in its early stage(s) (called a starting state) at the same time.\nOnly consider another new application if and when the previous application has transitioned out of the starting state.\nApplications will always be allocated resources on a first in first out basis based on submission time.\nThat means that an application that is newly added and in its starting phase will only get resources if applications in the later stages do not need any resources."),(0,n.yg)("p",null,"This algorithm will be implemented as an application sorting policy on a queue.\nThis allows specific queues to limit parallel application startup while other queues with different work loads can schedule without or with different limitations."),(0,n.yg)("h3",{id:"fallback-mechanism"},"Fallback mechanism"),(0,n.yg)("p",null,"A fallback mechanism has to be built into the algorithm.\nNot all applications will request more than one allocation.\nThe other case that has to be accounted for could be a misbehaving or a slow application.\nHaving an application stuck in the starting state could cause a scheduler livelock and starvation of other applications."),(0,n.yg)("p",null,"The fall back mechanism proposed is as simple as a time limit on the starting state.\nThis means that any application auto progresses out of the starting state.\nThe time limit will be set to five (5) minutes hard coded as a starting point and will not be made configurable."),(0,n.yg)("p",null,"The other fallback mechanism considered was making the number of allocations for the starting state configurable.\nThis option provided a number of issues which made it difficult to implement.\nOne of the main stumbling blocks is the fact that it requires the application submitter to specify the value.\nIt also does not guarantee that the application will leave the starting state either and does not fix the livelock issue.\nIf an application was submitted with five required allocation but due to issues during the run never asked for more than four then the livelock would still occur."),(0,n.yg)("p",null,"Setting a default of zero (0) would also not work as it would bypass the starting state.\nIt would make the sorting policy an opt-in instead of an opt-out.\nSetting a default of one (1) does not give us much enhancement to what we currently propose.\nIt makes the sorting policy an opt-out but does not give the cluster administrator any control over the scheduling behaviour.\nWeighing those against each other the proposal is to not make this configurable."),(0,n.yg)("h3",{id:"example-run"},"Example run"),(0,n.yg)("p",null,"Using Spark applications as an example: a new application can only be scheduled if the previous application has at least one (1) executor allocated."),(0,n.yg)("p",null,(0,n.yg)("img",{alt:"images",src:a(1302).A,width:"1344",height:"820"})),(0,n.yg)("p",null,"Assume we have the following Spark apps: App1 & App2 as in the diagram above. The applications were submitted in that order: App1 first, then App2. They were both submitted to the same queue."),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},"Both applications are in the queue waiting for the first allocation: accepted by the scheduler. App1 has requested driver D1 and App2 has requested driver D2."),(0,n.yg)("li",{parentName:"ol"},"The scheduler sorts the application and allows 1 accepted application to be scheduled (no starting applications yet): App1 as the oldest applications with an outstanding request is scheduled.",(0,n.yg)("br",{parentName:"li"}),"App1 is allocated its driver (D1) and progresses to starting.",(0,n.yg)("br",{parentName:"li"}),"App2 request for a driver is ignored as the scheduler is starting App1 (only 1 application in starting or accepted state is scheduled)."),(0,n.yg)("li",{parentName:"ol"},"App1 requests executors E11 and E12. The scheduler assigns E11 and E12. At this point the application state changes to running when it has at least 1 executor allocated."),(0,n.yg)("li",{parentName:"ol"},"App2 has been waiting to get the driver allocated. Since there are no applications in a starting state the scheduler looks at App2 which is in an accepted state. App2 moves from the accepted state to starting when the driver is allocated."),(0,n.yg)("li",{parentName:"ol"},"App2 requests its executor E21. The application state changes to running when E21 is allocated.")),(0,n.yg)("p",null,"This process would repeat itself for any new application submitted."))}u.isMDXComponent=!0},1302:(e,t,a)=>{a.d(t,{A:()=>i});const i=a.p+"assets/images/fifo-state-example-294dbf22ea35a750c8ad768c8760929d.png"}}]); \ No newline at end of file diff --git a/assets/js/f8b6f1ce.50e77be8.js b/assets/js/f8b6f1ce.50e77be8.js deleted file mode 100644 index 0a912f0d9f0..00000000000 --- a/assets/js/f8b6f1ce.50e77be8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5874],{58860:(e,n,t)=>{t.d(n,{xA:()=>d,yg:()=>m});var o=t(37953);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function l(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=o.createContext({}),s=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d=function(e){var n=s(e.components);return o.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},h=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=s(t),h=a,m=u["".concat(c,".").concat(h)]||u[h]||p[h]||r;return t?o.createElement(m,l(l({ref:n},d),{},{components:t})):o.createElement(m,l({ref:n},d))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,l=new Array(r);l[0]=h;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i[u]="string"==typeof e?e:a,l[1]=i;for(var s=2;s{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>s});var o=t(72994),a=(t(37953),t(58860));const r={id:"scheduler_core_design",title:"Scheduler Core Design"},l=void 0,i={unversionedId:"archived_design/scheduler_core_design",id:"archived_design/scheduler_core_design",title:"Scheduler Core Design",description:"\x3c!--",source:"@site/docs/archived_design/scheduler_core_design.md",sourceDirName:"archived_design",slug:"/archived_design/scheduler_core_design",permalink:"/docs/next/archived_design/scheduler_core_design",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler_core_design",title:"Scheduler Core Design"},sidebar:"docs",previous:{title:"Support K8s Predicates",permalink:"/docs/next/archived_design/predicates"},next:{title:"Cross Queue Preemption",permalink:"/docs/next/archived_design/cross_queue_preemption"}},c={},s=[{value:"Components:",id:"components",level:2},{value:"Scheduler API Server (RMProxy)",id:"scheduler-api-server-rmproxy",level:3},{value:"Scheduler Cache",id:"scheduler-cache",level:3},{value:"Scheduler Cache Event Handler",id:"scheduler-cache-event-handler",level:3},{value:"Admin Service",id:"admin-service",level:3},{value:"Scheduler and Preemptor",id:"scheduler-and-preemptor",level:3},{value:"Scheduler's responsibility",id:"schedulers-responsibility",level:2},{value:"Preemption",id:"preemption",level:2},{value:"Communication between Shim and Core",id:"communication-between-shim-and-core",level:2},{value:"Configurations & Semantics",id:"configurations--semantics",level:2},{value:"How scheduler do allocation",id:"how-scheduler-do-allocation",level:2},{value:"Flow of events",id:"flow-of-events",level:2}],d={toc:s},u="wrapper";function p(e){let{components:n,...t}=e;return(0,a.yg)(u,(0,o.A)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("admonition",{type:"caution"},(0,a.yg)("p",{parentName:"admonition"},"The scheduler core design has changed. ",(0,a.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-317"},"YUNIKORN-317")," was committed and has removed the scheduler cache.\nThis document will not be maintained and is just for historical reference.\nSee ",(0,a.yg)("a",{parentName:"p",href:"/docs/next/design/cache_removal"},"scheduler cache removal design"))),(0,a.yg)("p",null,"Github repo: ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-core"},"https://github.com/apache/yunikorn-core")),(0,a.yg)("p",null,"Scheduler core encapsulates all scheduling algorithms, it collects resources from underneath resource management\nplatforms (like YARN/K8s), and is responsible for container allocation requests. It makes the decision where is the\nbest spot for each request and then sends response allocations to the resource management platform.\nScheduler core is agnostic about underneath platforms, all the communications are through the ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface"},"scheduler interface"),"."),(0,a.yg)("h2",{id:"components"},"Components:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"\n +---------------+ +--------------+\n |K8s Shim | |YARN Shim |\n +---------------+ +--------------+\n\n +--------------+ +------------+\n Scheduler- | GRPC Protocol| |Go API |\n Interface: +--------------+ +------------+\n\n+---------------------------------------------------------------------------+\n +--------------------+\n |Scheduler API Server|\n +-------------+ +---------+----------+\n |AdminService | |\n +-------------+ |Write Ops +----------------+\n +-------------+ V ++Scheduler |\n |Configurator | +-------------------+ Allocate || And |\n +-------------+ |Cache Event Handler+<-----------------| |\n +----------\x3e +-------------------+ Preempt ++Preemptor |\n Update Cfg Handled by policies +----------------+\n + (Stateless)\n +------v--------+\n |Scheduler Cache|\n +---------------+\n +---------------------------------------------+\n |--------+ +------+ +----------+ +----------+ |\n ||Node | |Queue | |Allocation| |Requests | |\n |--------+ +------+ +----------+ +----------+ |\n +---------------------------------------------+\n")),(0,a.yg)("h3",{id:"scheduler-api-server-rmproxy"},"Scheduler API Server (RMProxy)"),(0,a.yg)("p",null,"Responsible for communication between RM and Scheduler, which implements scheduler-interface GRPC protocol,\nor just APIs. (For intra-process communication w/o Serde)."),(0,a.yg)("h3",{id:"scheduler-cache"},"Scheduler Cache"),(0,a.yg)("p",null,"Caches all data related to scheduler state, such as used resources of each queues, nodes, allocations.\nRelationship between allocations and nodes, etc. Should not include in-flight data for resource allocation.\nFor example to-be-preempted allocation candidates. Fair share resource of queues, etc."),(0,a.yg)("h3",{id:"scheduler-cache-event-handler"},"Scheduler Cache Event Handler"),(0,a.yg)("p",null,"Handles all events which needs to update scheduler internal state. So all the write operations will be carefully handled."),(0,a.yg)("h3",{id:"admin-service"},"Admin Service"),(0,a.yg)("p",null,"Handles request from Admin, which can also load configurations from storage and update scheduler policies."),(0,a.yg)("h3",{id:"scheduler-and-preemptor"},"Scheduler and Preemptor"),(0,a.yg)("p",null,"Handles Scheduler's internal state. (Which is not belong to scheduelr cache), such as internal reservations, etc.\nScheduler and preemptor will work together, make scheduling or preemption decisions. All allocate/preempt request\nwill be handled by event handler."),(0,a.yg)("h2",{id:"schedulers-responsibility"},"Scheduler's responsibility"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"According to resource usages between queues, sort queues, applications, and figure out order of application allocation. (This will be used by preemption as well)."),(0,a.yg)("li",{parentName:"ul"},"It is possible that we cannot satisfy some of the allocation request, we need to skip them and find next request."),(0,a.yg)("li",{parentName:"ul"},"It is possible that some allocation request cannot be satisfied because of resource fragmentation. We need to reserve room for such requests."),(0,a.yg)("li",{parentName:"ul"},"Different nodes may belong to different disjoint partitions, we can make independent scheduler runs"),(0,a.yg)("li",{parentName:"ul"},"Be able to config and change ordering policies for apps, queues."),(0,a.yg)("li",{parentName:"ul"},"Application can choose their own way to manage sort of nodes.")),(0,a.yg)("h2",{id:"preemption"},"Preemption"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},'It is important to know "who wants the resource", so we can do preemption based on allocation orders.'),(0,a.yg)("li",{parentName:"ul"},"When do preemption, it is also efficient to trigger allocation op. Think about how to do it."),(0,a.yg)("li",{parentName:"ul"},"Preemption needs to take care about queue resource balancing.")),(0,a.yg)("h2",{id:"communication-between-shim-and-core"},"Communication between Shim and Core"),(0,a.yg)("p",null,"YuniKorn-Shim (like ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-k8shim"},"https://github.com/apache/yunikorn-k8shim"),") communicates with core by\nusing scheduler-interface (",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface"},"https://github.com/apache/yunikorn-scheduler-interface"),").\nScheduler interface has Go API or GRPC. Currently, yunikorn-k8shim is using Go API to communicate with yunikorn-core\nto avoid extra overhead introduced by GRPC. "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Shim (like K8shim) first need to register with core:")," "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *RMProxy) RegisterResourceManager(request *si.RegisterResourceManagerRequest, callback api.ResourceManagerCallback) (*si.RegisterResourceManagerResponse, error)\n")),(0,a.yg)("p",null,"Which indicate ResourceManager's name, a callback function for updateResponse. The design of core is be able to do scheduling for multiple clusters (such as multiple K8s cluster) just with one core instance."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Shim interacts with core by invoking RMProxy's Update API frequently, which updates new allocation request, allocation to kill, node updates, etc.")," "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *RMProxy) Update(request *si.UpdateRequest) error\n")),(0,a.yg)("p",null,"Response of update (such as new allocated container) will be received by registered callback."),(0,a.yg)("h2",{id:"configurations--semantics"},"Configurations & Semantics"),(0,a.yg)("p",null,"Example of configuration:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Partition is name space.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Same queues can under different partitions, but enforced to have same hierarchy."),(0,a.yg)("p",{parentName:"li"}," Good:"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ / \\\n b c b c\n")),(0,a.yg)("p",{parentName:"li"},' Good (c in partition y acl=""):'),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ /\n b c b\n")),(0,a.yg)("p",{parentName:"li"}," Bad (c in different hierarchy)"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ / \\\n b c b d\n /\n c\n")),(0,a.yg)("p",{parentName:"li"}," Bad (Duplicated c)"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x\n a\n / \\\n b c\n /\nc\n\n"))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Different hierarchies can be added"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre",className:"language-scheduler-conf.yaml"},"partitions:\n - name: default\n queues:\n root:\n configs:\n acls:\n childrens:\n - a\n - b\n - c\n - ...\n a:\n configs:\n acls:\n capacity: (capacity is not allowed to set for root)\n max-capacity: ...\n mapping-policies:\n ...\n - name: partition_a:\n queues:\n root:...\n")))),(0,a.yg)("h2",{id:"how-scheduler-do-allocation"},"How scheduler do allocation"),(0,a.yg)("p",null,"Scheduler runs a separate goroutine to look at asks and available resources, and do resource allocation. Here's allocation logic in pseudo code: "),(0,a.yg)("p",null,"Entry point of scheduler allocation is ",(0,a.yg)("inlineCode",{parentName:"p"},"scheduler.go: func (s *Scheduler) schedule()")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"# First of all, YuniKorn has partition concept, a logical resource pool can consists\n# of one of multiple physical dis-joint partitions. It is similar to YARN's node\n# partition concept.\n\nfor partition : partitions:\n # YuniKorn can reserve allocations for picky asks (such as large request, etc.)\n # Before doing regular allocation, YuniKorn look at reservedAllocations first.\n for reservedAllocation : partition.reservedAllocations: \n reservedAllocation.tryAllocate(..)\n \n # After tried all reserved allocation, YuniKorn will go to regular allocation\n partition.tryAllocate(..)\n \n # If there's any allocation created, scheduler will create an AllocationProposal\n # and send to Cache to \"commit\" the AllocationProposal \n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation by hierchical of queues")),(0,a.yg)("p",null,"Inside ",(0,a.yg)("inlineCode",{parentName:"p"},"partition.tryAllocate")," "),(0,a.yg)("p",null,"It recursively traverse from root queue and down to lower level, for each level, logic is inside ",(0,a.yg)("inlineCode",{parentName:"p"},"pkg/scheduler/scheduling_queue.go func (sq *SchedulingQueue) tryAllocate")),(0,a.yg)("p",null,"Remember YuniKorn natively supports hierarchical of queues. For ParentQueue (which has sub queues under the parent queue), it uses queue's own sorting policy to sort subqueues and try to allocate from most preferred queue to least-preferred queue. "),(0,a.yg)("p",null,"For LeafQueue (which has applications inside the queue), it uses queue's own sorting policy to sort applications belong to the queue and allocate based on the sorted order. "),(0,a.yg)("p",null,"(All sorting policies can be configured differently at each level.) "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation by application")),(0,a.yg)("p",null,"When it goes to Application, see (",(0,a.yg)("inlineCode",{parentName:"p"},"scheduler_application.go: func (sa *SchedulingApplication) tryAllocate"),"), It first sort the pending resource requests belong to the application (based on requests' priority). And based on the selected request, and configured node-sorting policy, it sorts nodes belong to the partition and try to allocate resources on the sorted nodes. "),(0,a.yg)("p",null,"When application trying to allocate resources on nodes, it will invokes PredicatePlugin to make sure Shim can confirm the node is good. (For example K8shim runs predicates check for allocation pre-check)."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation completed by scheduler")," "),(0,a.yg)("p",null,"Once allocation is done, scheduler will create an AllocationProposal and send to Cache to do further check, we will cover details in the upcoming section."),(0,a.yg)("h2",{id:"flow-of-events"},"Flow of events"),(0,a.yg)("p",null,"Like mentioned before, all communications between components like RMProxy/Cache/Schedulers are done by using async event handler. "),(0,a.yg)("p",null,"RMProxy/Cache/Scheduler include local event queues and event handlers. RMProxy and Scheduler have only one queue (For example: ",(0,a.yg)("inlineCode",{parentName:"p"},"pkg/scheduler/scheduler.go: handleSchedulerEvent"),"), and Cache has two queues (One for events from RMProxy, and one for events from Scheduler, which is designed for better performance). "),(0,a.yg)("p",null,"We will talk about how events flowed between components: "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Events for ResourceManager registration and updates:")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"Update from ResourceManager -> RMProxy -> RMUpdateRequestEvent Send to Cache\nNew ResourceManager registration -> RMProxy -> RegisterRMEvent Send to Cache\n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache Handles RM Updates")," "),(0,a.yg)("p",null,"There're many fields inside RM Update event (",(0,a.yg)("inlineCode",{parentName:"p"},"RMUpdateRequestEvent"),"), among them, we have following categories: "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"1) Update for Application-related updates\n2) Update for New allocation ask and release. \n3) Node (Such as kubelet) update (New node, remove node, node resource change, etc.)\n")),(0,a.yg)("p",null,"More details can be found at: "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"func (m *ClusterInfo) processRMUpdateEvent(event *cacheevent.RMUpdateRequestEvent)\n\ninside cluster_info.go\n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache send RM updates to Scheduler")),(0,a.yg)("p",null,"For most cases, Cache propagate updates from RM to scheduler directly (including Application, Node, Asks, etc.). And it is possible that some updates from RM is not valid (such as adding an application to a non-existed queue), for such cases, cache can send an event back to RMProxy and notify the ResourceManager. (See ",(0,a.yg)("inlineCode",{parentName:"p"},"RMApplicationUpdateEvent.RejectedApplications"),")"),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache handles scheduler config")," "),(0,a.yg)("p",null,"Cache also handles scheduler's config changes, see"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *ClusterInfo) processRMConfigUpdateEvent(event *commonevents.ConfigUpdateRMEvent)\n")),(0,a.yg)("p",null,"Similar to other RM updates, it propages news to scheduelr."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Scheduler do allocation")),(0,a.yg)("p",null,"Once an AllocationProposal created by scheduler, scheduler sends ",(0,a.yg)("inlineCode",{parentName:"p"},"AllocationProposalBundleEvent")," to Cache to commit. "),(0,a.yg)("p",null,"Cache look at AllocationProposal under lock, and commit these proposals. The reason to do proposal/commit is Scheduler can run in multi-threads which could cause conflict for resource allocation. This approach is inspired by Borg/Omega/YARN Global Scheduling."),(0,a.yg)("p",null,"Cache checks more states such as queue resources, node resources (we cannot allocate more resource than nodes' available), etc. Once check is done, Cache updates internal data strcture and send confirmation to Scheduler to update the same, and scheduler sends allocated Allocation to RMProxy so Shim can do further options. For example, K8shim will ",(0,a.yg)("inlineCode",{parentName:"p"},"bind")," an allocation (POD) to kubelet."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"Job Add:\n--------\nRM -> Cache -> Scheduler (Implemented)\n\nJob Remove:\n-----------\nRM -> Scheduler -> Cache (Implemented)\nReleased allocations: (Same as normal release) (Implemented)\nNote: Make sure remove from scheduler first to avoid new allocated created. \n\nScheduling Request Add:\n-----------------------\nRM -> Cache -> Scheduler (Implemented)\nNote: Will check if requested job exists, queue exists, etc.\nWhen any request invalid:\n Cache -> RM (Implemented)\n Scheduler -> RM (Implemented)\n\nScheduling Request remove:\n------------------------- \nRM -> Scheduler -> Cache (Implemented)\nNote: Make sure removed from scheduler first to avoid new container allocated\n\nAllocation remove (Preemption) \n-----------------\nScheduler -> Cache -> RM (TODO)\n (confirmation)\n\nAllocation remove (RM voluntarilly ask)\n---------------------------------------\nRM -> Scheduler -> Cache -> RM. (Implemented)\n (confirmation)\n\nNode Add: \n---------\nRM -> Cache -> Scheduler (Implemented)\nNote: Inside Cache, update allocated resources.\nError handling: Reject Node to RM (Implemented)\n\nNode Remove: \n------------\nImplemented in cache side\nRM -> Scheduler -> Cache (TODO)\n\nAllocation Proposal:\n--------------------\nScheduler -> Cache -> RM\nWhen rejected/accepted:\n Cache -> Scheduler\n \nInitial: (TODO)\n--------\n1. Admin configured partitions\n2. Cache initializes\n3. Scheduler copies configurations\n\nRelations between Entities \n-------------------------\n1. RM includes one or multiple:\n - Partitions \n - Jobs\n - Nodes \n - Queues\n \n2. One queue: \n - Under one partition\n - Under one RM.\n \n3. One job: \n - Under one queue (Job with same name can under different partitions)\n - Under one partition\n\nRM registration: (TODO)\n----------------\n1. RM send registration\n2. If RM already registered, remove old one, including everything belong to RM.\n\nRM termination (TODO) \n--------------\nJust remove the old one.\n\nUpdate of queues (TODO) \n------------------------\nAdmin Service -> Cache\n\nAbout partition (TODO) \n-----------------------\nInternal partition need to be normalized, for example, RM specify node with partition = xyz. \nScheduler internally need to normalize it to _xyz\nThis need to be done by RMProxy\n\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f8b6f1ce.6dedc2c5.js b/assets/js/f8b6f1ce.6dedc2c5.js new file mode 100644 index 00000000000..914207e55c7 --- /dev/null +++ b/assets/js/f8b6f1ce.6dedc2c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5874],{58860:(e,n,t)=>{t.d(n,{xA:()=>d,yg:()=>m});var o=t(37953);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function l(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=o.createContext({}),s=function(e){var n=o.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d=function(e){var n=s(e.components);return o.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},h=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=s(t),h=a,m=u["".concat(c,".").concat(h)]||u[h]||p[h]||r;return t?o.createElement(m,l(l({ref:n},d),{},{components:t})):o.createElement(m,l({ref:n},d))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,l=new Array(r);l[0]=h;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i[u]="string"==typeof e?e:a,l[1]=i;for(var s=2;s{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>s});var o=t(72994),a=(t(37953),t(58860));const r={id:"scheduler_core_design",title:"Scheduler Core Design"},l=void 0,i={unversionedId:"archived_design/scheduler_core_design",id:"archived_design/scheduler_core_design",title:"Scheduler Core Design",description:"\x3c!--",source:"@site/docs/archived_design/scheduler_core_design.md",sourceDirName:"archived_design",slug:"/archived_design/scheduler_core_design",permalink:"/docs/next/archived_design/scheduler_core_design",draft:!1,tags:[],version:"current",frontMatter:{id:"scheduler_core_design",title:"Scheduler Core Design"},sidebar:"docs",previous:{title:"Support K8s Predicates",permalink:"/docs/next/archived_design/predicates"},next:{title:"Batch Workloads Ordering with StateAware Policy",permalink:"/docs/next/archived_design/state_aware_scheduling"}},c={},s=[{value:"Components:",id:"components",level:2},{value:"Scheduler API Server (RMProxy)",id:"scheduler-api-server-rmproxy",level:3},{value:"Scheduler Cache",id:"scheduler-cache",level:3},{value:"Scheduler Cache Event Handler",id:"scheduler-cache-event-handler",level:3},{value:"Admin Service",id:"admin-service",level:3},{value:"Scheduler and Preemptor",id:"scheduler-and-preemptor",level:3},{value:"Scheduler's responsibility",id:"schedulers-responsibility",level:2},{value:"Preemption",id:"preemption",level:2},{value:"Communication between Shim and Core",id:"communication-between-shim-and-core",level:2},{value:"Configurations & Semantics",id:"configurations--semantics",level:2},{value:"How scheduler do allocation",id:"how-scheduler-do-allocation",level:2},{value:"Flow of events",id:"flow-of-events",level:2}],d={toc:s},u="wrapper";function p(e){let{components:n,...t}=e;return(0,a.yg)(u,(0,o.A)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("admonition",{type:"caution"},(0,a.yg)("p",{parentName:"admonition"},"The scheduler core design has changed. ",(0,a.yg)("a",{parentName:"p",href:"https://issues.apache.org/jira/browse/YUNIKORN-317"},"YUNIKORN-317")," was committed and has removed the scheduler cache.\nThis document will not be maintained and is just for historical reference.\nSee ",(0,a.yg)("a",{parentName:"p",href:"/docs/next/design/cache_removal"},"scheduler cache removal design"))),(0,a.yg)("p",null,"Github repo: ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-core"},"https://github.com/apache/yunikorn-core")),(0,a.yg)("p",null,"Scheduler core encapsulates all scheduling algorithms, it collects resources from underneath resource management\nplatforms (like YARN/K8s), and is responsible for container allocation requests. It makes the decision where is the\nbest spot for each request and then sends response allocations to the resource management platform.\nScheduler core is agnostic about underneath platforms, all the communications are through the ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface"},"scheduler interface"),"."),(0,a.yg)("h2",{id:"components"},"Components:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"\n +---------------+ +--------------+\n |K8s Shim | |YARN Shim |\n +---------------+ +--------------+\n\n +--------------+ +------------+\n Scheduler- | GRPC Protocol| |Go API |\n Interface: +--------------+ +------------+\n\n+---------------------------------------------------------------------------+\n +--------------------+\n |Scheduler API Server|\n +-------------+ +---------+----------+\n |AdminService | |\n +-------------+ |Write Ops +----------------+\n +-------------+ V ++Scheduler |\n |Configurator | +-------------------+ Allocate || And |\n +-------------+ |Cache Event Handler+<-----------------| |\n +----------\x3e +-------------------+ Preempt ++Preemptor |\n Update Cfg Handled by policies +----------------+\n + (Stateless)\n +------v--------+\n |Scheduler Cache|\n +---------------+\n +---------------------------------------------+\n |--------+ +------+ +----------+ +----------+ |\n ||Node | |Queue | |Allocation| |Requests | |\n |--------+ +------+ +----------+ +----------+ |\n +---------------------------------------------+\n")),(0,a.yg)("h3",{id:"scheduler-api-server-rmproxy"},"Scheduler API Server (RMProxy)"),(0,a.yg)("p",null,"Responsible for communication between RM and Scheduler, which implements scheduler-interface GRPC protocol,\nor just APIs. (For intra-process communication w/o Serde)."),(0,a.yg)("h3",{id:"scheduler-cache"},"Scheduler Cache"),(0,a.yg)("p",null,"Caches all data related to scheduler state, such as used resources of each queues, nodes, allocations.\nRelationship between allocations and nodes, etc. Should not include in-flight data for resource allocation.\nFor example to-be-preempted allocation candidates. Fair share resource of queues, etc."),(0,a.yg)("h3",{id:"scheduler-cache-event-handler"},"Scheduler Cache Event Handler"),(0,a.yg)("p",null,"Handles all events which needs to update scheduler internal state. So all the write operations will be carefully handled."),(0,a.yg)("h3",{id:"admin-service"},"Admin Service"),(0,a.yg)("p",null,"Handles request from Admin, which can also load configurations from storage and update scheduler policies."),(0,a.yg)("h3",{id:"scheduler-and-preemptor"},"Scheduler and Preemptor"),(0,a.yg)("p",null,"Handles Scheduler's internal state. (Which is not belong to scheduelr cache), such as internal reservations, etc.\nScheduler and preemptor will work together, make scheduling or preemption decisions. All allocate/preempt request\nwill be handled by event handler."),(0,a.yg)("h2",{id:"schedulers-responsibility"},"Scheduler's responsibility"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"According to resource usages between queues, sort queues, applications, and figure out order of application allocation. (This will be used by preemption as well)."),(0,a.yg)("li",{parentName:"ul"},"It is possible that we cannot satisfy some of the allocation request, we need to skip them and find next request."),(0,a.yg)("li",{parentName:"ul"},"It is possible that some allocation request cannot be satisfied because of resource fragmentation. We need to reserve room for such requests."),(0,a.yg)("li",{parentName:"ul"},"Different nodes may belong to different disjoint partitions, we can make independent scheduler runs"),(0,a.yg)("li",{parentName:"ul"},"Be able to config and change ordering policies for apps, queues."),(0,a.yg)("li",{parentName:"ul"},"Application can choose their own way to manage sort of nodes.")),(0,a.yg)("h2",{id:"preemption"},"Preemption"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},'It is important to know "who wants the resource", so we can do preemption based on allocation orders.'),(0,a.yg)("li",{parentName:"ul"},"When do preemption, it is also efficient to trigger allocation op. Think about how to do it."),(0,a.yg)("li",{parentName:"ul"},"Preemption needs to take care about queue resource balancing.")),(0,a.yg)("h2",{id:"communication-between-shim-and-core"},"Communication between Shim and Core"),(0,a.yg)("p",null,"YuniKorn-Shim (like ",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-k8shim"},"https://github.com/apache/yunikorn-k8shim"),") communicates with core by\nusing scheduler-interface (",(0,a.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface"},"https://github.com/apache/yunikorn-scheduler-interface"),").\nScheduler interface has Go API or GRPC. Currently, yunikorn-k8shim is using Go API to communicate with yunikorn-core\nto avoid extra overhead introduced by GRPC. "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Shim (like K8shim) first need to register with core:")," "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *RMProxy) RegisterResourceManager(request *si.RegisterResourceManagerRequest, callback api.ResourceManagerCallback) (*si.RegisterResourceManagerResponse, error)\n")),(0,a.yg)("p",null,"Which indicate ResourceManager's name, a callback function for updateResponse. The design of core is be able to do scheduling for multiple clusters (such as multiple K8s cluster) just with one core instance."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Shim interacts with core by invoking RMProxy's Update API frequently, which updates new allocation request, allocation to kill, node updates, etc.")," "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *RMProxy) Update(request *si.UpdateRequest) error\n")),(0,a.yg)("p",null,"Response of update (such as new allocated container) will be received by registered callback."),(0,a.yg)("h2",{id:"configurations--semantics"},"Configurations & Semantics"),(0,a.yg)("p",null,"Example of configuration:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Partition is name space.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Same queues can under different partitions, but enforced to have same hierarchy."),(0,a.yg)("p",{parentName:"li"}," Good:"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ / \\\n b c b c\n")),(0,a.yg)("p",{parentName:"li"},' Good (c in partition y acl=""):'),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ /\n b c b\n")),(0,a.yg)("p",{parentName:"li"}," Bad (c in different hierarchy)"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x partition=y\n a a\n / \\ / \\\n b c b d\n /\n c\n")),(0,a.yg)("p",{parentName:"li"}," Bad (Duplicated c)"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre"}," partition=x\n a\n / \\\n b c\n /\nc\n\n"))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},"Different hierarchies can be added"),(0,a.yg)("pre",{parentName:"li"},(0,a.yg)("code",{parentName:"pre",className:"language-scheduler-conf.yaml"},"partitions:\n - name: default\n queues:\n root:\n configs:\n acls:\n childrens:\n - a\n - b\n - c\n - ...\n a:\n configs:\n acls:\n capacity: (capacity is not allowed to set for root)\n max-capacity: ...\n mapping-policies:\n ...\n - name: partition_a:\n queues:\n root:...\n")))),(0,a.yg)("h2",{id:"how-scheduler-do-allocation"},"How scheduler do allocation"),(0,a.yg)("p",null,"Scheduler runs a separate goroutine to look at asks and available resources, and do resource allocation. Here's allocation logic in pseudo code: "),(0,a.yg)("p",null,"Entry point of scheduler allocation is ",(0,a.yg)("inlineCode",{parentName:"p"},"scheduler.go: func (s *Scheduler) schedule()")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"# First of all, YuniKorn has partition concept, a logical resource pool can consists\n# of one of multiple physical dis-joint partitions. It is similar to YARN's node\n# partition concept.\n\nfor partition : partitions:\n # YuniKorn can reserve allocations for picky asks (such as large request, etc.)\n # Before doing regular allocation, YuniKorn look at reservedAllocations first.\n for reservedAllocation : partition.reservedAllocations: \n reservedAllocation.tryAllocate(..)\n \n # After tried all reserved allocation, YuniKorn will go to regular allocation\n partition.tryAllocate(..)\n \n # If there's any allocation created, scheduler will create an AllocationProposal\n # and send to Cache to \"commit\" the AllocationProposal \n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation by hierchical of queues")),(0,a.yg)("p",null,"Inside ",(0,a.yg)("inlineCode",{parentName:"p"},"partition.tryAllocate")," "),(0,a.yg)("p",null,"It recursively traverse from root queue and down to lower level, for each level, logic is inside ",(0,a.yg)("inlineCode",{parentName:"p"},"pkg/scheduler/scheduling_queue.go func (sq *SchedulingQueue) tryAllocate")),(0,a.yg)("p",null,"Remember YuniKorn natively supports hierarchical of queues. For ParentQueue (which has sub queues under the parent queue), it uses queue's own sorting policy to sort subqueues and try to allocate from most preferred queue to least-preferred queue. "),(0,a.yg)("p",null,"For LeafQueue (which has applications inside the queue), it uses queue's own sorting policy to sort applications belong to the queue and allocate based on the sorted order. "),(0,a.yg)("p",null,"(All sorting policies can be configured differently at each level.) "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation by application")),(0,a.yg)("p",null,"When it goes to Application, see (",(0,a.yg)("inlineCode",{parentName:"p"},"scheduler_application.go: func (sa *SchedulingApplication) tryAllocate"),"), It first sort the pending resource requests belong to the application (based on requests' priority). And based on the selected request, and configured node-sorting policy, it sorts nodes belong to the partition and try to allocate resources on the sorted nodes. "),(0,a.yg)("p",null,"When application trying to allocate resources on nodes, it will invokes PredicatePlugin to make sure Shim can confirm the node is good. (For example K8shim runs predicates check for allocation pre-check)."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Allocation completed by scheduler")," "),(0,a.yg)("p",null,"Once allocation is done, scheduler will create an AllocationProposal and send to Cache to do further check, we will cover details in the upcoming section."),(0,a.yg)("h2",{id:"flow-of-events"},"Flow of events"),(0,a.yg)("p",null,"Like mentioned before, all communications between components like RMProxy/Cache/Schedulers are done by using async event handler. "),(0,a.yg)("p",null,"RMProxy/Cache/Scheduler include local event queues and event handlers. RMProxy and Scheduler have only one queue (For example: ",(0,a.yg)("inlineCode",{parentName:"p"},"pkg/scheduler/scheduler.go: handleSchedulerEvent"),"), and Cache has two queues (One for events from RMProxy, and one for events from Scheduler, which is designed for better performance). "),(0,a.yg)("p",null,"We will talk about how events flowed between components: "),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Events for ResourceManager registration and updates:")),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"Update from ResourceManager -> RMProxy -> RMUpdateRequestEvent Send to Cache\nNew ResourceManager registration -> RMProxy -> RegisterRMEvent Send to Cache\n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache Handles RM Updates")," "),(0,a.yg)("p",null,"There're many fields inside RM Update event (",(0,a.yg)("inlineCode",{parentName:"p"},"RMUpdateRequestEvent"),"), among them, we have following categories: "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"1) Update for Application-related updates\n2) Update for New allocation ask and release. \n3) Node (Such as kubelet) update (New node, remove node, node resource change, etc.)\n")),(0,a.yg)("p",null,"More details can be found at: "),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"func (m *ClusterInfo) processRMUpdateEvent(event *cacheevent.RMUpdateRequestEvent)\n\ninside cluster_info.go\n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache send RM updates to Scheduler")),(0,a.yg)("p",null,"For most cases, Cache propagate updates from RM to scheduler directly (including Application, Node, Asks, etc.). And it is possible that some updates from RM is not valid (such as adding an application to a non-existed queue), for such cases, cache can send an event back to RMProxy and notify the ResourceManager. (See ",(0,a.yg)("inlineCode",{parentName:"p"},"RMApplicationUpdateEvent.RejectedApplications"),")"),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Cache handles scheduler config")," "),(0,a.yg)("p",null,"Cache also handles scheduler's config changes, see"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-go"},"func (m *ClusterInfo) processRMConfigUpdateEvent(event *commonevents.ConfigUpdateRMEvent)\n")),(0,a.yg)("p",null,"Similar to other RM updates, it propages news to scheduelr."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Scheduler do allocation")),(0,a.yg)("p",null,"Once an AllocationProposal created by scheduler, scheduler sends ",(0,a.yg)("inlineCode",{parentName:"p"},"AllocationProposalBundleEvent")," to Cache to commit. "),(0,a.yg)("p",null,"Cache look at AllocationProposal under lock, and commit these proposals. The reason to do proposal/commit is Scheduler can run in multi-threads which could cause conflict for resource allocation. This approach is inspired by Borg/Omega/YARN Global Scheduling."),(0,a.yg)("p",null,"Cache checks more states such as queue resources, node resources (we cannot allocate more resource than nodes' available), etc. Once check is done, Cache updates internal data strcture and send confirmation to Scheduler to update the same, and scheduler sends allocated Allocation to RMProxy so Shim can do further options. For example, K8shim will ",(0,a.yg)("inlineCode",{parentName:"p"},"bind")," an allocation (POD) to kubelet."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre"},"Job Add:\n--------\nRM -> Cache -> Scheduler (Implemented)\n\nJob Remove:\n-----------\nRM -> Scheduler -> Cache (Implemented)\nReleased allocations: (Same as normal release) (Implemented)\nNote: Make sure remove from scheduler first to avoid new allocated created. \n\nScheduling Request Add:\n-----------------------\nRM -> Cache -> Scheduler (Implemented)\nNote: Will check if requested job exists, queue exists, etc.\nWhen any request invalid:\n Cache -> RM (Implemented)\n Scheduler -> RM (Implemented)\n\nScheduling Request remove:\n------------------------- \nRM -> Scheduler -> Cache (Implemented)\nNote: Make sure removed from scheduler first to avoid new container allocated\n\nAllocation remove (Preemption) \n-----------------\nScheduler -> Cache -> RM (TODO)\n (confirmation)\n\nAllocation remove (RM voluntarilly ask)\n---------------------------------------\nRM -> Scheduler -> Cache -> RM. (Implemented)\n (confirmation)\n\nNode Add: \n---------\nRM -> Cache -> Scheduler (Implemented)\nNote: Inside Cache, update allocated resources.\nError handling: Reject Node to RM (Implemented)\n\nNode Remove: \n------------\nImplemented in cache side\nRM -> Scheduler -> Cache (TODO)\n\nAllocation Proposal:\n--------------------\nScheduler -> Cache -> RM\nWhen rejected/accepted:\n Cache -> Scheduler\n \nInitial: (TODO)\n--------\n1. Admin configured partitions\n2. Cache initializes\n3. Scheduler copies configurations\n\nRelations between Entities \n-------------------------\n1. RM includes one or multiple:\n - Partitions \n - Jobs\n - Nodes \n - Queues\n \n2. One queue: \n - Under one partition\n - Under one RM.\n \n3. One job: \n - Under one queue (Job with same name can under different partitions)\n - Under one partition\n\nRM registration: (TODO)\n----------------\n1. RM send registration\n2. If RM already registered, remove old one, including everything belong to RM.\n\nRM termination (TODO) \n--------------\nJust remove the old one.\n\nUpdate of queues (TODO) \n------------------------\nAdmin Service -> Cache\n\nAbout partition (TODO) \n-----------------------\nInternal partition need to be normalized, for example, RM specify node with partition = xyz. \nScheduler internally need to normalize it to _xyz\nThis need to be done by RMProxy\n\n")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fd3398f1.78600dcb.js b/assets/js/fd3398f1.78600dcb.js new file mode 100644 index 00000000000..7313d80fb97 --- /dev/null +++ b/assets/js/fd3398f1.78600dcb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[72903],{58860:(e,n,t)=>{t.d(n,{xA:()=>d,yg:()=>m});var i=t(37953);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),c=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},d=function(e){var n=c(e.components);return i.createElement(l.Provider,{value:n},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},g=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(t),g=r,m=p["".concat(l,".").concat(g)]||p[g]||u[g]||o;return t?i.createElement(m,a(a({ref:n},d),{},{components:t})):i.createElement(m,a({ref:n},d))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,a=new Array(o);a[0]=g;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[p]="string"==typeof e?e:r,a[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var i=t(72994),r=(t(37953),t(58860));const o={id:"resilience",title:"Resilience"},a=void 0,s={unversionedId:"design/resilience",id:"design/resilience",title:"Resilience",description:"\x3c!--",source:"@site/docs/design/resilience.md",sourceDirName:"design",slug:"/design/resilience",permalink:"/docs/next/design/resilience",draft:!1,tags:[],version:"current",frontMatter:{id:"resilience",title:"Resilience"},sidebar:"docs",previous:{title:"Priority Scheduling",permalink:"/docs/next/design/priority_scheduling"},next:{title:"Configuration V2",permalink:"/docs/next/design/config_v2"}},l={},c=[{value:"The problem",id:"the-problem",level:2},{value:"Design",id:"design",level:2},{value:"Workflow",id:"workflow",level:3},{value:"How to determine recovery is complete?",id:"how-to-determine-recovery-is-complete",level:3},{value:"Node recovery",id:"node-recovery",level:3},{value:"Requests for recovery",id:"requests-for-recovery",level:3},{value:"Applications",id:"applications",level:4},{value:"Nodes and allocations",id:"nodes-and-allocations",level:4}],d={toc:c},p="wrapper";function u(e){let{components:n,...o}=e;return(0,r.yg)(p,(0,i.A)({},d,o,{components:n,mdxType:"MDXLayout"}),(0,r.yg)("p",null,"This is not a HA (High-availability) design, HA implies that a service can\nsurvive from a fatal software/hardware failure. That requires one or more\nstandby instances providing same services to take over active instance on failures.\nResilience here means for YuniKorn, we can restart it without losing its state."),(0,r.yg)("h2",{id:"the-problem"},"The problem"),(0,r.yg)("p",null,"YuniKorn is designed as a stateless service, it doesn't persist its state, e.g\napplications/queues/allocations etc, to any persistent storage. All states are\nin memory only. This design ensures YuniKorn to be able to response requests with\nlow latency, and deployment mode is simple. However, a restart (or recovery) will\nhave the problem to lose state data. We need a decent way to reconstruct all\nprevious states on a restart."),(0,r.yg)("h2",{id:"design"},"Design"),(0,r.yg)("h3",{id:"workflow"},"Workflow"),(0,r.yg)("p",null,'Scheduler core has no notion of "state", which means it does not know if it is under recovering.\nIt is too complex to maintain a series of ',(0,r.yg)("inlineCode",{parentName:"p"},"scheduler states")," in both core and shim, because we must\nkeep them in-sync. However, if we live under a simple assumption: ",(0,r.yg)("strong",{parentName:"p"},"scheduler core only responses\nrequests, the correction of requests is ensured by shim according its current state"),".\nThe design becomes much simpler. This way, the shim maintains a state machine like below. When\nit is under ",(0,r.yg)("inlineCode",{parentName:"p"},"running")," state, it sends new requests to the scheduler core as long as a new one is found;\nwhen under ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering")," state, it collects previous allocations and send recovery messages to\nthe scheduler core, and waiting for recovery to be accomplished."),(0,r.yg)("p",null,"Shim scheduler state machine"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"}," Register Recover Success\nNew -----------\x3e Registered -----------\x3e Recovering ----------\x3e Running\n | Fail\n --------\x3e Failed\n")),(0,r.yg)("p",null,"Following chart illustrate how yunikorn-core and shim works together on recovery."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Workflow",src:t(82526).A,width:"7198",height:"2222"})),(0,r.yg)("p",null,"Restart (with recovery) process"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"yunikorn-shim registers itself with yunikorn-core"),(0,r.yg)("li",{parentName:"ul"},'shim enters "recovering" state. Under "recovering" state, the shim only scans existing nodes and allocations, no new scheduling requests will be sent.',(0,r.yg)("ul",{parentName:"li"},(0,r.yg)("li",{parentName:"ul"},"shim scans existing nodes from api-server and added them to cache"),(0,r.yg)("li",{parentName:"ul"},"shim scans existing pods from api-server, filter out the pods that already assigned (scheduled to a node), and added that to cache (allocation in that node)"),(0,r.yg)("li",{parentName:"ul"},"shim sends update request to yunikorn-core with the info found in previous steps"))),(0,r.yg)("li",{parentName:"ul"},"yunikorn-core handles update requests, the steps should look like a replay of allocation process, including",(0,r.yg)("ul",{parentName:"li"},(0,r.yg)("li",{parentName:"ul"},"adding node"),(0,r.yg)("li",{parentName:"ul"},"adding applications"),(0,r.yg)("li",{parentName:"ul"},"adding allocations"),(0,r.yg)("li",{parentName:"ul"},"modifying queue resources"),(0,r.yg)("li",{parentName:"ul"},"update partition info"))),(0,r.yg)("li",{parentName:"ul"},'when all nodes are fully recovered, shim transits the state to "running"'),(0,r.yg)("li",{parentName:"ul"},'shim notifies yunikorn-core that recovery is done, then yunikorn-core transits to "running" state.')),(0,r.yg)("h3",{id:"how-to-determine-recovery-is-complete"},"How to determine recovery is complete?"),(0,r.yg)("p",null,"Shim queries K8s api-server to get how many nodes were available in this cluster. It tracks the recovering status of each node.\nOnce all nodes are recovered, it can claim the recovery is completed. This approach requires us to add ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering")," and ",(0,r.yg)("inlineCode",{parentName:"p"},"recovered"),"\nstates to nodes' state machine in the shim."),(0,r.yg)("h3",{id:"node-recovery"},"Node recovery"),(0,r.yg)("p",null,"In the shim layer, it maintains states for each node and pods running on this node. When start to recover nodes,\nall nodes initially are considered as under ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering"),". Only when all pods running on this node are fully recovered,\nthe node can be considered as ",(0,r.yg)("inlineCode",{parentName:"p"},"recovered"),"."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"node-recovery",src:t(21829).A,width:"6426",height:"2489"})),(0,r.yg)("p",null,"Like demonstrated on upon diagram,"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Node0 is still recovering because pod0 is recovering."),(0,r.yg)("li",{parentName:"ul"},"Node1 is recovered (become schedulable) because all pods on this node have been recovered."),(0,r.yg)("li",{parentName:"ul"},"Node2 is lost, shim lost contact with this node. If after sometime this node comes back, shim should still try to recover this node.")),(0,r.yg)("h3",{id:"requests-for-recovery"},"Requests for recovery"),(0,r.yg)("p",null,"During recovery process, shim needs to collect all known information of applications, nodes and allocations from the underneath\nResource Manager and use them for recovery."),(0,r.yg)("h4",{id:"applications"},"Applications"),(0,r.yg)("p",null,"Existing applications must be recovered first before allocations. Shim needs to scan all existing applications\nfrom nodes, and add applications info as a list of ",(0,r.yg)("inlineCode",{parentName:"p"},"AddApplicationRequest")," in the ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest"),". This is same\nas the fresh application submission."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"message AddApplicationRequest {\n string applicationID = 1;\n string queueName = 2;\n string partitionName = 3;\n}\n")),(0,r.yg)("h4",{id:"nodes-and-allocations"},"Nodes and allocations"),(0,r.yg)("p",null,"Once a shim is registered to the scheduler-core, subsequent requests are sent via ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest#NewNodeInfo"),"\n(see more from ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface/blob/master/si.proto"},"si.proto"),").\nThe structure of the messages looks like,"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"message NewNodeInfo {\n // nodeID\n string nodeID = 1;\n // optional node attributes\n map attributes = 2;\n // total node resource\n Resource schedulableResource = 3;\n // existing allocations on this node\n repeated Allocation existingAllocations = 4;\n}\n")),(0,r.yg)("p",null,"Shim needs to scan all existing allocations on a node and wrap these info up as a ",(0,r.yg)("inlineCode",{parentName:"p"},"NewNodeInfo"),", add that to a\n",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," and then send to scheduler-core."),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Note"),": the recovery of existing allocations depend on the existence of applications, which means applications must\nbe recovered first. Since scheduler-core handles ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," one by one, it is required that all existing allocations\nin a ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," must from known applications or new applications embedded within the same ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest"),", which can be\nspecified in ",(0,r.yg)("inlineCode",{parentName:"p"},"NewApplications")," field. Scheduler-core ensures ",(0,r.yg)("inlineCode",{parentName:"p"},"NewApplications")," are always processed first."))}u.isMDXComponent=!0},21829:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/resilience-node-recovery-6abe663c243bdfdbff691e14a70166e5.jpg"},82526:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/resilience-workflow-191f147a7501740ec6632f216f2bb25f.jpg"}}]); \ No newline at end of file diff --git a/assets/js/fd3398f1.a366367f.js b/assets/js/fd3398f1.a366367f.js deleted file mode 100644 index 37badb869e9..00000000000 --- a/assets/js/fd3398f1.a366367f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[72903],{58860:(e,n,t)=>{t.d(n,{xA:()=>d,yg:()=>m});var i=t(37953);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),c=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},d=function(e){var n=c(e.components);return i.createElement(l.Provider,{value:n},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},g=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(t),g=r,m=p["".concat(l,".").concat(g)]||p[g]||u[g]||o;return t?i.createElement(m,a(a({ref:n},d),{},{components:t})):i.createElement(m,a({ref:n},d))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,a=new Array(o);a[0]=g;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[p]="string"==typeof e?e:r,a[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var i=t(72994),r=(t(37953),t(58860));const o={id:"resilience",title:"Resilience"},a=void 0,s={unversionedId:"design/resilience",id:"design/resilience",title:"Resilience",description:"\x3c!--",source:"@site/docs/design/resilience.md",sourceDirName:"design",slug:"/design/resilience",permalink:"/docs/next/design/resilience",draft:!1,tags:[],version:"current",frontMatter:{id:"resilience",title:"Resilience"},sidebar:"docs",previous:{title:"Priority Scheduling",permalink:"/docs/next/design/priority_scheduling"},next:{title:"Batch Workloads Ordering with StateAware Policy",permalink:"/docs/next/design/state_aware_scheduling"}},l={},c=[{value:"The problem",id:"the-problem",level:2},{value:"Design",id:"design",level:2},{value:"Workflow",id:"workflow",level:3},{value:"How to determine recovery is complete?",id:"how-to-determine-recovery-is-complete",level:3},{value:"Node recovery",id:"node-recovery",level:3},{value:"Requests for recovery",id:"requests-for-recovery",level:3},{value:"Applications",id:"applications",level:4},{value:"Nodes and allocations",id:"nodes-and-allocations",level:4}],d={toc:c},p="wrapper";function u(e){let{components:n,...o}=e;return(0,r.yg)(p,(0,i.A)({},d,o,{components:n,mdxType:"MDXLayout"}),(0,r.yg)("p",null,"This is not a HA (High-availability) design, HA implies that a service can\nsurvive from a fatal software/hardware failure. That requires one or more\nstandby instances providing same services to take over active instance on failures.\nResilience here means for YuniKorn, we can restart it without losing its state."),(0,r.yg)("h2",{id:"the-problem"},"The problem"),(0,r.yg)("p",null,"YuniKorn is designed as a stateless service, it doesn't persist its state, e.g\napplications/queues/allocations etc, to any persistent storage. All states are\nin memory only. This design ensures YuniKorn to be able to response requests with\nlow latency, and deployment mode is simple. However, a restart (or recovery) will\nhave the problem to lose state data. We need a decent way to reconstruct all\nprevious states on a restart."),(0,r.yg)("h2",{id:"design"},"Design"),(0,r.yg)("h3",{id:"workflow"},"Workflow"),(0,r.yg)("p",null,'Scheduler core has no notion of "state", which means it does not know if it is under recovering.\nIt is too complex to maintain a series of ',(0,r.yg)("inlineCode",{parentName:"p"},"scheduler states")," in both core and shim, because we must\nkeep them in-sync. However, if we live under a simple assumption: ",(0,r.yg)("strong",{parentName:"p"},"scheduler core only responses\nrequests, the correction of requests is ensured by shim according its current state"),".\nThe design becomes much simpler. This way, the shim maintains a state machine like below. When\nit is under ",(0,r.yg)("inlineCode",{parentName:"p"},"running")," state, it sends new requests to the scheduler core as long as a new one is found;\nwhen under ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering")," state, it collects previous allocations and send recovery messages to\nthe scheduler core, and waiting for recovery to be accomplished."),(0,r.yg)("p",null,"Shim scheduler state machine"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"}," Register Recover Success\nNew -----------\x3e Registered -----------\x3e Recovering ----------\x3e Running\n | Fail\n --------\x3e Failed\n")),(0,r.yg)("p",null,"Following chart illustrate how yunikorn-core and shim works together on recovery."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Workflow",src:t(82526).A,width:"7198",height:"2222"})),(0,r.yg)("p",null,"Restart (with recovery) process"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"yunikorn-shim registers itself with yunikorn-core"),(0,r.yg)("li",{parentName:"ul"},'shim enters "recovering" state. Under "recovering" state, the shim only scans existing nodes and allocations, no new scheduling requests will be sent.',(0,r.yg)("ul",{parentName:"li"},(0,r.yg)("li",{parentName:"ul"},"shim scans existing nodes from api-server and added them to cache"),(0,r.yg)("li",{parentName:"ul"},"shim scans existing pods from api-server, filter out the pods that already assigned (scheduled to a node), and added that to cache (allocation in that node)"),(0,r.yg)("li",{parentName:"ul"},"shim sends update request to yunikorn-core with the info found in previous steps"))),(0,r.yg)("li",{parentName:"ul"},"yunikorn-core handles update requests, the steps should look like a replay of allocation process, including",(0,r.yg)("ul",{parentName:"li"},(0,r.yg)("li",{parentName:"ul"},"adding node"),(0,r.yg)("li",{parentName:"ul"},"adding applications"),(0,r.yg)("li",{parentName:"ul"},"adding allocations"),(0,r.yg)("li",{parentName:"ul"},"modifying queue resources"),(0,r.yg)("li",{parentName:"ul"},"update partition info"))),(0,r.yg)("li",{parentName:"ul"},'when all nodes are fully recovered, shim transits the state to "running"'),(0,r.yg)("li",{parentName:"ul"},'shim notifies yunikorn-core that recovery is done, then yunikorn-core transits to "running" state.')),(0,r.yg)("h3",{id:"how-to-determine-recovery-is-complete"},"How to determine recovery is complete?"),(0,r.yg)("p",null,"Shim queries K8s api-server to get how many nodes were available in this cluster. It tracks the recovering status of each node.\nOnce all nodes are recovered, it can claim the recovery is completed. This approach requires us to add ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering")," and ",(0,r.yg)("inlineCode",{parentName:"p"},"recovered"),"\nstates to nodes' state machine in the shim."),(0,r.yg)("h3",{id:"node-recovery"},"Node recovery"),(0,r.yg)("p",null,"In the shim layer, it maintains states for each node and pods running on this node. When start to recover nodes,\nall nodes initially are considered as under ",(0,r.yg)("inlineCode",{parentName:"p"},"recovering"),". Only when all pods running on this node are fully recovered,\nthe node can be considered as ",(0,r.yg)("inlineCode",{parentName:"p"},"recovered"),"."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"node-recovery",src:t(21829).A,width:"6426",height:"2489"})),(0,r.yg)("p",null,"Like demonstrated on upon diagram,"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Node0 is still recovering because pod0 is recovering."),(0,r.yg)("li",{parentName:"ul"},"Node1 is recovered (become schedulable) because all pods on this node have been recovered."),(0,r.yg)("li",{parentName:"ul"},"Node2 is lost, shim lost contact with this node. If after sometime this node comes back, shim should still try to recover this node.")),(0,r.yg)("h3",{id:"requests-for-recovery"},"Requests for recovery"),(0,r.yg)("p",null,"During recovery process, shim needs to collect all known information of applications, nodes and allocations from the underneath\nResource Manager and use them for recovery."),(0,r.yg)("h4",{id:"applications"},"Applications"),(0,r.yg)("p",null,"Existing applications must be recovered first before allocations. Shim needs to scan all existing applications\nfrom nodes, and add applications info as a list of ",(0,r.yg)("inlineCode",{parentName:"p"},"AddApplicationRequest")," in the ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest"),". This is same\nas the fresh application submission."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"message AddApplicationRequest {\n string applicationID = 1;\n string queueName = 2;\n string partitionName = 3;\n}\n")),(0,r.yg)("h4",{id:"nodes-and-allocations"},"Nodes and allocations"),(0,r.yg)("p",null,"Once a shim is registered to the scheduler-core, subsequent requests are sent via ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest#NewNodeInfo"),"\n(see more from ",(0,r.yg)("a",{parentName:"p",href:"https://github.com/apache/yunikorn-scheduler-interface/blob/master/si.proto"},"si.proto"),").\nThe structure of the messages looks like,"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre"},"message NewNodeInfo {\n // nodeID\n string nodeID = 1;\n // optional node attributes\n map attributes = 2;\n // total node resource\n Resource schedulableResource = 3;\n // existing allocations on this node\n repeated Allocation existingAllocations = 4;\n}\n")),(0,r.yg)("p",null,"Shim needs to scan all existing allocations on a node and wrap these info up as a ",(0,r.yg)("inlineCode",{parentName:"p"},"NewNodeInfo"),", add that to a\n",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," and then send to scheduler-core."),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Note"),": the recovery of existing allocations depend on the existence of applications, which means applications must\nbe recovered first. Since scheduler-core handles ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," one by one, it is required that all existing allocations\nin a ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest")," must from known applications or new applications embedded within the same ",(0,r.yg)("inlineCode",{parentName:"p"},"UpdateRequest"),", which can be\nspecified in ",(0,r.yg)("inlineCode",{parentName:"p"},"NewApplications")," field. Scheduler-core ensures ",(0,r.yg)("inlineCode",{parentName:"p"},"NewApplications")," are always processed first."))}u.isMDXComponent=!0},21829:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/resilience-node-recovery-6abe663c243bdfdbff691e14a70166e5.jpg"},82526:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/resilience-workflow-191f147a7501740ec6632f216f2bb25f.jpg"}}]); \ No newline at end of file diff --git a/assets/js/main.0bd5df42.js b/assets/js/main.0bd5df42.js deleted file mode 100644 index 7fa1d3ae0b3..00000000000 --- a/assets/js/main.0bd5df42.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.0bd5df42.js.LICENSE.txt */ -(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[38792],{86004:(e,n,t)=>{"use strict";t.d(n,{W:()=>r});var o=t(37953);function r(){return o.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},o.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},32859:(e,n,t)=>{var o={"./":3895};function r(e){var n=s(e);return t(n)}function s(e){if(!t.o(o,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=s,e.exports=r,r.id=32859},47862:(e,n,t)=>{"use strict";t.d(n,{A:()=>g});var o=t(37953),r=t(72994),s=t(67020),i=t.n(s),a=t(84054);const c={"00aed75b":[()=>t.e(86547).then(t.bind(t,92525)),"@site/versioned_docs/version-0.11.0/api/system.md",92525],"0131ba20":[()=>t.e(51791).then(t.bind(t,75015)),"@site/versioned_docs/version-1.0.0/design/k8shim.md",75015],"01627567":[()=>t.e(5415).then(t.bind(t,65406)),"@site/versioned_docs/version-1.3.0/user_guide/priorities.md",65406],"0203cbc2":[()=>t.e(23714).then(t.bind(t,24506)),"@site/versioned_docs/version-1.5.0/performance/profiling.md",24506],"024f5110":[()=>t.e(34654).then(t.bind(t,33144)),"@site/versioned_docs/version-0.11.0/api/cluster.md",33144],"026b0f1d":[()=>t.e(95520).then(t.bind(t,14085)),"@site/versioned_docs/version-1.4.0/design/scheduler_object_states.md",14085],"02ad889d":[()=>t.e(29853).then(t.bind(t,90520)),"@site/versioned_docs/version-0.12.1/user_guide/queue_config.md",90520],"02b8ff39":[()=>t.e(65867).then(t.bind(t,16119)),"@site/versioned_docs/version-1.3.0/archived_design/k8shim.md",16119],"03ef24a9":[()=>t.e(70921).then(t.bind(t,86952)),"@site/versioned_docs/version-0.9.0/api/system.md",86952],"0448914c":[()=>t.e(34786).then(t.bind(t,1156)),"@site/versioned_docs/version-1.1.0/design/scheduler_configuration.md",1156],"04768086":[()=>t.e(2450).then(t.bind(t,31937)),"@site/versioned_docs/version-1.4.0/performance/evaluate_perf_function_with_kubemark.md",31937],"04f00c7c":[()=>t.e(86260).then(t.bind(t,79947)),"@site/versioned_docs/version-1.3.0/api/system.md",79947],"04f5229b":[()=>t.e(89173).then(t.bind(t,13015)),"@site/versioned_docs/version-0.12.2/user_guide/workloads/run_tensorflow.md",13015],"04f93611":[()=>t.e(16081).then(t.bind(t,79522)),"@site/versioned_docs/version-0.11.0/design/gang_scheduling.md",79522],"0519d6ff":[()=>t.e(4946).then(t.bind(t,69589)),"@site/versioned_docs/version-0.12.2/design/scheduler_configuration.md",69589],"055b225f":[()=>t.e(92802).then(t.t.bind(t,18991,19)),"~docs/default/version-1-2-0-metadata-prop-01e.json",18991],"0565d9f4":[()=>t.e(23014).then(t.bind(t,12628)),"@site/docs/design/generic_resource.md",12628],"067a7414":[()=>t.e(37571).then(t.bind(t,6356)),"@site/versioned_docs/version-0.12.2/api/system.md",6356],"0734b534":[()=>t.e(87683).then(t.bind(t,38327)),"@site/versioned_docs/version-1.5.0/get_started/core_features.md",38327],"073760cf":[()=>t.e(60043).then(t.bind(t,6876)),"@site/docs/design/historical_usage_tracking.md",6876],"075bf599":[()=>t.e(54784).then(t.bind(t,45373)),"@site/versioned_docs/version-1.5.0/design/cache_removal.md",45373],"0780ab69":[()=>t.e(81270).then(t.bind(t,4976)),"@site/versioned_docs/version-1.2.0/design/config_v2.md",4976],"07de990d":[()=>t.e(73171).then(t.bind(t,75335)),"@site/versioned_docs/version-1.1.0/api/scheduler.md",75335],"0810aeb4":[()=>t.e(28112).then(t.t.bind(t,57757,19)),"/yunikorn-site/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",57757],"086d5e3f":[()=>t.e(536).then(t.bind(t,37490)),"@site/versioned_docs/version-0.9.0/user_guide/resource_quota_mgmt.md",37490],"08958cc8":[()=>t.e(7727).then(t.bind(t,35e3)),"@site/versioned_docs/version-1.5.0/user_guide/use_case.md",35e3],"08b63e68":[()=>t.e(19109).then(t.bind(t,71043)),"@site/versioned_docs/version-1.5.0/performance/performance_tutorial.md",71043],"08ea7f98":[()=>t.e(39013).then(t.bind(t,282)),"@site/versioned_docs/version-1.2.0/design/interface_message_simplification.md",282],"098cffed":[()=>t.e(23626).then(t.bind(t,28408)),"@site/versioned_docs/version-0.8.0/design/scheduler_configuration.md",28408],"09920c24":[()=>t.e(36154).then(t.bind(t,64894)),"@site/versioned_docs/version-1.2.0/get_started/core_features.md",64894],"09fd6bc3":[()=>t.e(70706).then(t.bind(t,78899)),"@site/src/pages/community/events.md",78899],"0a87ba36":[()=>t.e(86673).then(t.bind(t,38189)),"@site/docs/performance/metrics.md",38189],"0b0c644f":[()=>t.e(14162).then(t.bind(t,6066)),"@site/versioned_docs/version-1.5.0/user_guide/service_config.md",6066],"0b0ea5f1":[()=>t.e(83045).then(t.bind(t,31928)),"@site/versioned_docs/version-1.5.0/user_guide/priorities.md",31928],"0b7eabf3":[()=>t.e(72913).then(t.bind(t,37092)),"@site/versioned_docs/version-1.3.0/get_started/get_started.md",37092],"0b9c6e63":[()=>t.e(2123).then(t.bind(t,31778)),"@site/versioned_docs/version-1.1.0/developer_guide/dependencies.md",31778],"0c902ed6":[()=>t.e(54426).then(t.bind(t,25053)),"@site/docs/design/state_aware_scheduling.md",25053],"0cd5b1a7":[()=>t.e(98206).then(t.bind(t,7196)),"@site/docs/performance/evaluate_perf_function_with_kubemark.md",7196],"0dc95480":[()=>t.e(48724).then(t.bind(t,63051)),"@site/versioned_docs/version-0.12.1/design/state_aware_scheduling.md",63051],"0dcca658":[()=>t.e(19699).then(t.bind(t,6701)),"@site/versioned_docs/version-1.1.0/user_guide/trouble_shooting.md",6701],"0e6e7f1a":[()=>t.e(16248).then(t.bind(t,14932)),"@site/versioned_docs/version-1.4.0/get_started/core_features.md",14932],"0f3f8c85":[()=>t.e(2960).then(t.bind(t,72226)),"@site/versioned_docs/version-1.0.0/design/architecture.md",72226],"0fe0ccc7":[()=>t.e(93978).then(t.bind(t,94589)),"@site/versioned_docs/version-1.1.0/design/state_aware_scheduling.md",94589],"0ffa903f":[()=>t.e(70806).then(t.bind(t,82198)),"@site/src/pages/community/index.js",82198],"1072df95":[()=>t.e(36347).then(t.bind(t,9368)),"@site/versioned_docs/version-0.11.0/user_guide/gang_scheduling.md",9368],"1094d3ac":[()=>t.e(97220).then(t.bind(t,59323)),"@site/versioned_docs/version-0.10.0/design/predicates.md",59323],"116ce0e0":[()=>t.e(59960).then(t.bind(t,24392)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/run_mpi.md",24392],"12af6885":[()=>t.e(85812).then(t.bind(t,113)),"@site/docs/design/simple_preemptor.md",113],"12c7c638":[()=>t.e(91494).then(t.bind(t,26778)),"@site/versioned_docs/version-0.12.2/design/architecture.md",26778],"131f5b8d":[()=>t.e(81367).then(t.bind(t,64660)),"@site/src/pages/release-announce/0.11.0.md",64660],"1394ac74":[()=>t.e(58241).then(t.bind(t,6207)),"@site/versioned_docs/version-1.5.0/metrics/runtime.md",6207],"139f73fe":[()=>t.e(45623).then(t.bind(t,62486)),"@site/versioned_docs/version-0.9.0/performance/metrics.md",62486],"13b56c59":[()=>t.e(76635).then(t.bind(t,18129)),"@site/versioned_docs/version-0.9.0/performance/evaluate_perf_function_with_kubemark.md",18129],"13f29f79":[()=>t.e(4886).then(t.bind(t,81126)),"@site/src/pages/community/download.md",81126],"15659d54":[()=>t.e(95966).then(t.bind(t,66846)),"@site/versioned_docs/version-1.0.0/design/state_aware_scheduling.md",66846],"1582f434":[()=>t.e(64660).then(t.bind(t,80641)),"@site/docs/design/user_group_manager.md",80641],"15abff36":[()=>t.e(42839).then(t.bind(t,69901)),"@site/versioned_docs/version-0.10.0/performance/profiling.md",69901],"15d1a8b2":[()=>t.e(32287).then(t.bind(t,55233)),"@site/versioned_docs/version-1.5.0/api/system.md",55233],"1626930f":[()=>t.e(3640).then(t.bind(t,94527)),"@site/versioned_docs/version-0.11.0/api/scheduler.md",94527],"174d46b8":[()=>t.e(28107).then(t.bind(t,13382)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/workload_overview.md",13382],17896441:[()=>Promise.all([t.e(71869),t.e(16821),t.e(18401)]).then(t.bind(t,25184)),"@theme/DocItem",25184],"178e95a2":[()=>t.e(11157).then(t.bind(t,90117)),"@site/versioned_docs/version-1.3.0/archived_design/scheduler_core_design.md",90117],"17c1bf74":[()=>t.e(56158).then(t.bind(t,80202)),"@site/versioned_docs/version-0.8.0/performance/profiling.md",80202],"17c79707":[()=>t.e(79862).then(t.bind(t,23721)),"@site/versioned_docs/version-0.9.0/user_guide/workloads/run_spark.md",23721],"17e08b0c":[()=>t.e(5005).then(t.bind(t,46975)),"@site/versioned_docs/version-1.4.0/user_guide/use_case.md",46975],"197162c9":[()=>t.e(10325).then(t.bind(t,57080)),"@site/versioned_docs/version-0.12.2/design/resilience.md",57080],"19d98c6a":[()=>t.e(7292).then(t.bind(t,79331)),"@site/versioned_docs/version-1.4.0/design/gang_scheduling.md",79331],"19e8550d":[()=>t.e(36).then(t.bind(t,66941)),"@site/versioned_docs/version-0.12.2/performance/profiling.md",66941],"1a38f637":[()=>t.e(81542).then(t.bind(t,6610)),"@site/docs/get_started/get_started.md",6610],"1a4e3797":[()=>Promise.all([t.e(71869),t.e(62138)]).then(t.bind(t,12421)),"@theme/SearchPage",12421],"1a7d2b73":[()=>t.e(49294).then(t.bind(t,76043)),"@site/versioned_docs/version-0.12.1/user_guide/placement_rules.md",76043],"1a8d89d5":[()=>t.e(13089).then(t.bind(t,27212)),"@site/versioned_docs/version-1.2.0/design/user_group_manager.md",27212],"1b5b94bb":[()=>t.e(77564).then(t.bind(t,73755)),"@site/versioned_docs/version-0.8.0/community/coding_guidelines.md",73755],"1be78505":[()=>Promise.all([t.e(71869),t.e(88714)]).then(t.bind(t,64847)),"@theme/DocPage",64847],"1c9209f4":[()=>t.e(65429).then(t.bind(t,94266)),"@site/versioned_docs/version-1.3.0/design/generic_resource.md",94266],"1cb009e2":[()=>t.e(4105).then(t.bind(t,30363)),"@site/versioned_docs/version-0.9.0/api/cluster.md",30363],"1cb70b87":[()=>t.e(64575).then(t.bind(t,24953)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/run_spark.md",24953],"1d098224":[()=>t.e(44077).then(t.bind(t,97108)),"@site/versioned_docs/version-0.9.0/user_guide/sorting_policies.md",97108],"1d314591":[()=>t.e(51103).then(t.bind(t,26848)),"@site/versioned_docs/version-1.1.0/user_guide/gang_scheduling.md",26848],"1dcb712d":[()=>t.e(57813).then(t.bind(t,38086)),"@site/versioned_docs/version-0.12.2/user_guide/usergroup_resolution.md",38086],"1dea1673":[()=>t.e(54357).then(t.t.bind(t,4061,19)),"/yunikorn-site/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",4061],"1df0bf2a":[()=>t.e(94485).then(t.bind(t,86944)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/workload_overview.md",86944],"1e0f4596":[()=>t.e(25871).then(t.bind(t,52565)),"@site/versioned_docs/version-0.10.0/developer_guide/env_setup.md",52565],"1e32b83f":[()=>t.e(84795).then(t.bind(t,13832)),"@site/src/pages/release-announce/1.1.0.md",13832],"1e6876ab":[()=>t.e(45681).then(t.bind(t,99335)),"@site/versioned_docs/version-1.3.0/developer_guide/openshift_development.md",99335],"1ef3c4cb":[()=>t.e(3210).then(t.bind(t,59358)),"@site/versioned_docs/version-0.12.2/user_guide/workloads/run_flink.md",59358],"1f391b9e":[()=>Promise.all([t.e(71869),t.e(16821),t.e(66061)]).then(t.bind(t,71458)),"@theme/MDXPage",71458],"1f466884":[()=>t.e(89838).then(t.bind(t,2082)),"@site/docs/user_guide/queue_config.md",2082],"1f5d5f87":[()=>t.e(68047).then(t.bind(t,93654)),"@site/versioned_docs/version-0.9.0/user_guide/trouble_shooting.md",93654],"1f87d76b":[()=>t.e(34062).then(t.bind(t,89360)),"@site/versioned_docs/version-1.2.0/user_guide/resource_quota_mgmt.md",89360],"1fec1075":[()=>t.e(72405).then(t.bind(t,68863)),"@site/src/pages/release-announce/0.10.0.md",68863],"203393bb":[()=>t.e(10783).then(t.bind(t,91731)),"@site/docs/developer_guide/scheduler_object_states.md",91731],"203f692a":[()=>t.e(28922).then(t.bind(t,81182)),"@site/versioned_docs/version-1.3.0/performance/evaluate_perf_function_with_kubemark.md",81182],"20d575d4":[()=>t.e(14140).then(t.bind(t,20207)),"@site/versioned_docs/version-1.1.0/performance/performance_tutorial.md",20207],"21fffddb":[()=>t.e(65880).then(t.bind(t,87465)),"@site/src/pages/release-announce/1.2.0.md",87465],"22290b7c":[()=>t.e(1316).then(t.bind(t,4875)),"@site/versioned_docs/version-1.5.0/design/priority_scheduling.md",4875],"229fac93":[()=>t.e(37586).then(t.bind(t,64988)),"@site/src/pages/community/how_to_contribute.md",64988],"22d92bf3":[()=>t.e(47063).then(t.bind(t,37552)),"@site/versioned_docs/version-0.12.1/user_guide/usergroup_resolution.md",37552],"2308dcf3":[()=>t.e(94852).then(t.bind(t,49989)),"@site/versioned_docs/version-1.1.0/api/system.md",49989],"23b73747":[()=>t.e(74838).then(t.bind(t,29181)),"@site/versioned_docs/version-1.3.0/design/interface_message_simplification.md",29181],"244eac16":[()=>t.e(51645).then(t.bind(t,45921)),"@site/versioned_docs/version-1.2.0/design/generic_resource.md",45921],"24bb3679":[()=>t.e(77494).then(t.bind(t,43470)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/run_tensorflow.md",43470],"253fbb59":[()=>t.e(77177).then(t.bind(t,43417)),"@site/versioned_docs/version-1.4.0/get_started/get_started.md",43417],25778245:[()=>t.e(63625).then(t.bind(t,60495)),"@site/versioned_docs/version-0.11.0/user_guide/resource_quota_mgmt.md",60495],"259c64e2":[()=>t.e(97239).then(t.bind(t,46122)),"@site/versioned_docs/version-1.5.0/developer_guide/env_setup.md",46122],"26c8b3d3":[()=>t.e(66324).then(t.bind(t,98606)),"@site/versioned_docs/version-1.2.0/developer_guide/build.md",98606],"2757bf0a":[()=>t.e(41399).then(t.bind(t,23065)),"@site/versioned_docs/version-1.1.0/user_guide/usergroup_resolution.md",23065],"2774336d":[()=>t.e(24451).then(t.bind(t,30994)),"@site/versioned_docs/version-1.4.0/developer_guide/openshift_development.md",30994],"278ee235":[()=>t.e(42018).then(t.bind(t,62167)),"@site/versioned_docs/version-1.3.0/user_guide/acls.md",62167],"27e1f4b3":[()=>t.e(74259).then(t.bind(t,84312)),"@site/versioned_docs/version-0.12.2/user_guide/placement_rules.md",84312],"28164c5f":[()=>t.e(14602).then(t.bind(t,62448)),"@site/versioned_docs/version-1.5.0/metrics/queue.md",62448],"284c0406":[()=>t.e(9768).then(t.bind(t,82634)),"@site/versioned_docs/version-0.9.0/design/namespace_resource_quota.md",82634],"284fa5fb":[()=>t.e(33109).then(t.bind(t,83976)),"@site/versioned_docs/version-1.2.0/design/priority_scheduling.md",83976],"288b5fa4":[()=>t.e(25661).then(t.bind(t,43585)),"@site/versioned_docs/version-1.4.0/design/scheduler_configuration.md",43585],"29295ff3":[()=>t.e(39667).then(t.bind(t,82497)),"@site/versioned_docs/version-1.4.0/developer_guide/env_setup.md",82497],"293bee56":[()=>t.e(32968).then(t.bind(t,16779)),"@site/versioned_docs/version-0.12.2/design/predicates.md",16779],"2999c86a":[()=>t.e(53036).then(t.bind(t,57013)),"@site/versioned_docs/version-1.5.0/design/simple_preemptor.md",57013],"29a3d0d6":[()=>t.e(49706).then(t.bind(t,39634)),"@site/versioned_docs/version-0.9.0/user_guide/workloads/run_flink.md",39634],"2a3c922d":[()=>t.e(89845).then(t.bind(t,53740)),"@site/versioned_docs/version-1.1.0/design/scheduler_core_design.md",53740],"2acaeb1a":[()=>t.e(84927).then(t.bind(t,50774)),"@site/versioned_docs/version-1.2.0/archived_design/predicates.md",50774],"2b10040d":[()=>t.e(43516).then(t.bind(t,71932)),"@site/versioned_docs/version-1.4.0/user_guide/preemption.md",71932],"2b4143dc":[()=>t.e(40802).then(t.bind(t,11367)),"@site/versioned_docs/version-1.3.0/design/state_aware_scheduling.md",11367],"2c019423":[()=>t.e(30749).then(t.bind(t,53239)),"@site/versioned_docs/version-0.9.0/design/cross_queue_preemption.md",53239],"2cdd7720":[()=>t.e(77630).then(t.bind(t,10588)),"@site/versioned_docs/version-1.0.0/design/cache_removal.md",10588],"2e1bbbbe":[()=>t.e(72982).then(t.bind(t,37674)),"@site/versioned_docs/version-1.0.0/user_guide/trouble_shooting.md",37674],"2f626edb":[()=>t.e(43162).then(t.bind(t,99939)),"@site/versioned_docs/version-1.3.0/archived_design/cross_queue_preemption.md",99939],"2fbebc4d":[()=>t.e(96529).then(t.bind(t,75791)),"@site/versioned_docs/version-1.3.0/user_guide/placement_rules.md",75791],"30b0614b":[()=>t.e(17657).then(t.bind(t,97694)),"@site/versioned_docs/version-0.12.2/design/namespace_resource_quota.md",97694],"30de4b0c":[()=>t.e(5886).then(t.bind(t,32150)),"@site/versioned_docs/version-1.1.0/performance/profiling.md",32150],"30fe064f":[()=>t.e(96321).then(t.bind(t,93478)),"@site/versioned_docs/version-1.3.0/user_guide/troubleshooting.md",93478],"31c3b644":[()=>t.e(83553).then(t.bind(t,12775)),"@site/versioned_docs/version-0.11.0/design/resilience.md",12775],"31dd2b75":[()=>t.e(359).then(t.bind(t,92751)),"@site/versioned_docs/version-1.0.0/user_guide/workloads/run_tensorflow.md",92751],"3259ac92":[()=>t.e(82495).then(t.bind(t,41855)),"@site/docs/design/config_v2.md",41855],"32947c92":[()=>t.e(71560).then(t.bind(t,35429)),"@site/versioned_docs/version-1.3.0/api/scheduler.md",35429],"33031c96":[()=>t.e(59783).then(t.bind(t,20269)),"@site/versioned_docs/version-1.2.0/design/k8shim.md",20269],"330bcee0":[()=>t.e(89732).then(t.bind(t,15178)),"@site/versioned_docs/version-0.12.1/user_guide/workloads/run_tensorflow.md",15178],"333ae3de":[()=>t.e(62112).then(t.bind(t,15871)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/run_spark.md",15871],"3384d06b":[()=>t.e(8725).then(t.t.bind(t,30031,19)),"~docs/default/version-0-12-1-metadata-prop-a75.json",30031],"33aa855a":[()=>t.e(42856).then(t.bind(t,89086)),"@site/versioned_docs/version-0.12.1/design/k8shim.md",89086],"33b8ac1d":[()=>t.e(97884).then(t.bind(t,241)),"@site/versioned_docs/version-0.12.2/design/scheduler_object_states.md",241],"34003c72":[()=>t.e(89983).then(t.bind(t,35776)),"@site/versioned_docs/version-0.8.0/configuration/queue_config.md",35776],"341034ab":[()=>t.e(8853).then(t.bind(t,98131)),"@site/versioned_docs/version-1.5.0/design/config_v2.md",98131],"34672d36":[()=>t.e(60042).then(t.bind(t,16382)),"@site/versioned_docs/version-1.0.0/user_guide/resource_quota_mgmt.md",16382],"3484cec4":[()=>t.e(66115).then(t.bind(t,93889)),"@site/versioned_docs/version-1.1.0/design/architecture.md",93889],"34af491e":[()=>t.e(50528).then(t.bind(t,492)),"@site/versioned_docs/version-0.9.0/user_guide/placement_rules.md",492],"34d88677":[()=>t.e(51030).then(t.bind(t,81100)),"@site/versioned_docs/version-0.11.0/design/predicates.md",81100],"354854e1":[()=>t.e(12646).then(t.bind(t,54420)),"@site/versioned_docs/version-1.3.0/developer_guide/dependencies.md",54420],"3619f683":[()=>t.e(81745).then(t.bind(t,33486)),"@site/versioned_docs/version-1.5.0/user_guide/queue_config.md",33486],"3683234c":[()=>t.e(8641).then(t.bind(t,59957)),"@site/versioned_docs/version-1.5.0/design/preemption.md",59957],"36f1c627":[()=>t.e(69085).then(t.bind(t,59611)),"@site/versioned_docs/version-1.0.0/developer_guide/dependencies.md",59611],"3826374e":[()=>t.e(77993).then(t.bind(t,95773)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/run_tensorflow.md",95773],"392e1a00":[()=>t.e(82206).then(t.bind(t,95696)),"@site/docs/user_guide/troubleshooting.md",95696],"39455ce1":[()=>t.e(81848).then(t.bind(t,65913)),"@site/versioned_docs/version-1.2.0/design/cross_queue_preemption.md",65913],"3951a3d5":[()=>t.e(61056).then(t.bind(t,26157)),"@site/versioned_docs/version-1.0.0/user_guide/gang_scheduling.md",26157],"39e6d37f":[()=>t.e(32102).then(t.bind(t,38486)),"@site/versioned_docs/version-1.2.0/design/cache_removal.md",38486],"3b084a86":[()=>t.e(9371).then(t.bind(t,45877)),"@site/versioned_docs/version-0.12.2/user_guide/queue_config.md",45877],"3bfd86a6":[()=>t.e(27029).then(t.bind(t,7428)),"@site/versioned_docs/version-0.10.0/design/pluggable_app_management.md",7428],"3c15e784":[()=>t.e(66303).then(t.bind(t,14554)),"@site/versioned_docs/version-0.12.2/performance/metrics.md",14554],"3c851dde":[()=>t.e(7202).then(t.bind(t,40131)),"@site/versioned_docs/version-1.4.0/user_guide/priorities.md",40131],"3cbcee45":[()=>t.e(10467).then(t.bind(t,48181)),"@site/versioned_docs/version-1.5.0/user_guide/usergroup_resolution.md",48181],"3d1791fa":[()=>t.e(33523).then(t.bind(t,32266)),"@site/versioned_docs/version-0.8.0/setup/env_setup.md",32266],"3dd193dd":[()=>t.e(10571).then(t.bind(t,88601)),"@site/versioned_docs/version-1.3.0/design/config_v2.md",88601],"3dd644e6":[()=>t.e(32861).then(t.bind(t,71732)),"@site/versioned_docs/version-1.0.0/design/scheduler_plugin.md",71732],"3deac311":[()=>t.e(32272).then(t.bind(t,18435)),"@site/versioned_docs/version-1.4.0/metrics/queue.md",18435],"3e90f77d":[()=>t.e(31872).then(t.bind(t,35370)),"@site/versioned_docs/version-1.2.0/design/pluggable_app_management.md",35370],"3f297b93":[()=>t.e(49232).then(t.bind(t,70246)),"@site/versioned_docs/version-0.12.1/developer_guide/deployment.md",70246],"3f50cac0":[()=>t.e(81618).then(t.bind(t,45421)),"@site/versioned_docs/version-0.12.1/design/pluggable_app_management.md",45421],"3f99eb33":[()=>t.e(39561).then(t.bind(t,71154)),"@site/versioned_docs/version-0.12.2/user_guide/acls.md",71154],"4171ae7f":[()=>t.e(94075).then(t.bind(t,18151)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/run_flink.md",18151],"427c3667":[()=>t.e(89753).then(t.bind(t,26836)),"@site/docs/user_guide/deployment_modes.md",26836],"4293d558":[()=>t.e(83683).then(t.bind(t,92428)),"@site/versioned_docs/version-1.3.0/performance/profiling.md",92428],"42e8cbb3":[()=>t.e(93124).then(t.bind(t,61637)),"@site/versioned_docs/version-1.5.0/archived_design/cross_queue_preemption.md",61637],"42f05cce":[()=>t.e(92747).then(t.bind(t,11630)),"@site/versioned_docs/version-0.10.0/user_guide/workloads/run_flink.md",11630],"432ba8c0":[()=>t.e(97642).then(t.bind(t,12206)),"@site/versioned_docs/version-1.2.0/archived_design/cross_queue_preemption.md",12206],"4356428f":[()=>t.e(95105).then(t.bind(t,52586)),"@site/docs/design/gang_scheduling.md",52586],"43a73887":[()=>t.e(55570).then(t.bind(t,68731)),"@site/versioned_docs/version-0.12.2/design/cross_queue_preemption.md",68731],"43c45fbd":[()=>t.e(49042).then(t.bind(t,67926)),"@site/docs/performance/profiling.md",67926],"442d4849":[()=>t.e(6368).then(t.bind(t,20517)),"@site/versioned_docs/version-0.10.0/user_guide/queue_config.md",20517],"447f169e":[()=>t.e(80047).then(t.bind(t,55048)),"@site/versioned_docs/version-1.2.0/design/simple_preemptor.md",55048],45113257:[()=>t.e(50763).then(t.bind(t,43826)),"@site/versioned_docs/version-1.3.0/developer_guide/deployment.md",43826],"45a2a32a":[()=>t.e(42656).then(t.bind(t,96903)),"@site/versioned_docs/version-0.12.1/design/namespace_resource_quota.md",96903],"45af7cbe":[()=>t.e(30090).then(t.bind(t,80581)),"@site/versioned_docs/version-1.5.0/design/architecture.md",80581],"45f98d44":[()=>t.e(46137).then(t.bind(t,32473)),"@site/versioned_docs/version-0.11.0/design/cache_removal.md",32473],"4677217b":[()=>t.e(95843).then(t.bind(t,21275)),"@site/versioned_docs/version-1.3.0/design/cache_removal.md",21275],"474cf6da":[()=>t.e(55286).then(t.bind(t,54657)),"@site/versioned_docs/version-1.2.0/user_guide/priorities.md",54657],"47b8b18c":[()=>t.e(82862).then(t.bind(t,78308)),"@site/docs/design/scheduler_configuration.md",78308],"47d3ce37":[()=>t.e(97185).then(t.bind(t,46318)),"@site/versioned_docs/version-1.5.0/archived_design/pluggable_app_management.md",46318],"481cf853":[()=>t.e(84933).then(t.bind(t,99145)),"@site/versioned_docs/version-0.11.0/design/architecture.md",99145],"484362c2":[()=>t.e(59911).then(t.bind(t,24833)),"@site/docs/developer_guide/openshift_development.md",24833],"48b422ba":[()=>t.e(69166).then(t.bind(t,9743)),"@site/versioned_docs/version-1.2.0/user_guide/troubleshooting.md",9743],"48c9bcee":[()=>t.e(83416).then(t.bind(t,5152)),"@site/versioned_docs/version-0.12.1/design/gang_scheduling.md",5152],"49077a33":[()=>t.e(70747).then(t.bind(t,11659)),"@site/versioned_docs/version-1.4.0/api/cluster.md",11659],"495df45a":[()=>t.e(16337).then(t.bind(t,17964)),"@site/versioned_docs/version-1.0.0/design/interface_message_simplification.md",17964],"4bbb5eb1":[()=>t.e(31412).then(t.bind(t,30783)),"@site/docs/design/priority_scheduling.md",30783],"4bbb7f4a":[()=>t.e(78023).then(t.bind(t,88870)),"@site/versioned_docs/version-1.4.0/performance/metrics.md",88870],"4be882fd":[()=>t.e(97766).then(t.bind(t,90937)),"@site/versioned_docs/version-0.9.0/user_guide/queue_config.md",90937],"4c517393":[()=>t.e(72780).then(t.bind(t,55204)),"@site/src/pages/release-announce/1.5.0.md",55204],"4cd336cf":[()=>t.e(85739).then(t.bind(t,37269)),"@site/versioned_docs/version-1.1.0/user_guide/acls.md",37269],"4d53942d":[()=>t.e(53870).then(t.bind(t,87432)),"@site/docs/user_guide/workloads/run_tensorflow.md",87432],"4d985d8a":[()=>t.e(67270).then(t.bind(t,32271)),"@site/versioned_docs/version-0.12.2/design/k8shim.md",32271],"4e1badf8":[()=>t.e(84838).then(t.bind(t,88611)),"@site/versioned_docs/version-0.8.0/setup/build_local.md",88611],"4fd3fe56":[()=>t.e(21672).then(t.bind(t,47808)),"@site/docs/user_guide/prometheus.md",47808],"4ff49acf":[()=>t.e(40570).then(t.bind(t,35880)),"@site/docs/design/user_group_enforcement.md",35880],"506691da":[()=>t.e(89907).then(t.bind(t,97569)),"@site/versioned_docs/version-0.10.0/design/scheduler_object_states.md",97569],"51392a58":[()=>t.e(88353).then(t.bind(t,93651)),"@site/versioned_docs/version-0.11.0/user_guide/workloads/run_flink.md",93651],"5166b893":[()=>t.e(56107).then(t.bind(t,18777)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/workload_overview.md",18777],"5188416b":[()=>t.e(10836).then(t.t.bind(t,37828,19)),"~docs/default/version-1-3-0-metadata-prop-3af.json",37828],"52045c4e":[()=>t.e(28079).then(t.bind(t,11894)),"@site/versioned_docs/version-1.3.0/user_guide/prometheus.md",11894],"528dfaf3":[()=>t.e(24616).then(t.bind(t,48205)),"@site/versioned_docs/version-0.8.0/design/namespace_resource_quota.md",48205],"529f7014":[()=>t.e(31609).then(t.bind(t,44072)),"@site/versioned_docs/version-1.4.0/archived_design/cross_queue_preemption.md",44072],"532b25e9":[()=>t.e(62242).then(t.bind(t,78564)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/run_tensorflow.md",78564],"5345c07d":[()=>Promise.all([t.e(71869),t.e(79322)]).then(t.bind(t,8114)),"@site/versioned_docs/version-1.5.0/metrics/scheduler.mdx",8114],"53ba98a8":[()=>t.e(61408).then(t.bind(t,96830)),"@site/versioned_docs/version-0.11.0/performance/profiling.md",96830],"53c63e3f":[()=>t.e(19411).then(t.bind(t,24915)),"@site/versioned_docs/version-0.8.0/configuration/placement_rules.md",24915],"53d6c163":[()=>t.e(6988).then(t.bind(t,27748)),"@site/versioned_docs/version-1.5.0/user_guide/prometheus.md",27748],"54213aa1":[()=>t.e(9045).then(t.bind(t,33700)),"@site/src/pages/release-announce/0.8.0.md",33700],"548a188b":[()=>t.e(4432).then(t.bind(t,43881)),"@site/versioned_docs/version-0.12.1/developer_guide/build.md",43881],"548f5e59":[()=>t.e(57346).then(t.bind(t,68592)),"@site/versioned_docs/version-1.1.0/developer_guide/deployment.md",68592],"54b2a591":[()=>t.e(51800).then(t.bind(t,24146)),"@site/versioned_docs/version-0.10.0/user_guide/trouble_shooting.md",24146],"559ca816":[()=>t.e(96751).then(t.bind(t,74870)),"@site/versioned_docs/version-0.12.2/design/state_aware_scheduling.md",74870],"5603f239":[()=>t.e(58969).then(t.bind(t,88605)),"@site/versioned_docs/version-0.12.2/performance/evaluate_perf_function_with_kubemark.md",88605],"564cd4c0":[()=>t.e(11200).then(t.bind(t,43728)),"@site/versioned_docs/version-0.12.1/get_started/get_started.md",43728],"5652c446":[()=>t.e(18500).then(t.bind(t,97184)),"@site/versioned_docs/version-0.11.0/design/cross_queue_preemption.md",97184],"56be068b":[()=>t.e(46001).then(t.bind(t,59476)),"@site/versioned_docs/version-0.12.2/design/cache_removal.md",59476],"56f4e815":[()=>t.e(55449).then(t.bind(t,32718)),"@site/versioned_docs/version-1.4.0/design/preemption.md",32718],57176175:[()=>t.e(73204).then(t.bind(t,9204)),"@site/versioned_docs/version-1.1.0/design/predicates.md",9204],"579c441c":[()=>t.e(73607).then(t.bind(t,98201)),"@site/docs/user_guide/usergroup_resolution.md",98201],"57d3a897":[()=>t.e(9591).then(t.bind(t,83663)),"@site/versioned_docs/version-1.2.0/design/scheduler_configuration.md",83663],58082863:[()=>t.e(76047).then(t.bind(t,72257)),"@site/versioned_docs/version-0.12.1/user_guide/workloads/run_flink.md",72257],"58597cf2":[()=>t.e(38620).then(t.bind(t,69561)),"@site/versioned_docs/version-1.4.0/performance/profiling.md",69561],"5877df2d":[()=>t.e(74618).then(t.bind(t,53542)),"@site/versioned_docs/version-1.0.0/design/namespace_resource_quota.md",53542],"58a729ec":[()=>t.e(64727).then(t.bind(t,46863)),"@site/versioned_docs/version-1.5.0/archived_design/scheduler_core_design.md",46863],"59ca9e65":[()=>t.e(91416).then(t.bind(t,8431)),"@site/versioned_docs/version-1.4.0/developer_guide/dependencies.md",8431],"5a396677":[()=>t.e(13299).then(t.bind(t,79958)),"@site/versioned_docs/version-1.5.0/user_guide/labels_and_annotations_in_yunikorn.md",79958],"5a3f9071":[()=>t.e(26021).then(t.bind(t,34583)),"@site/versioned_docs/version-1.1.0/design/interface_message_simplification.md",34583],"5ae3e876":[()=>t.e(69061).then(t.bind(t,48689)),"@site/src/pages/community/people.md",48689],"5ba37eca":[()=>t.e(36598).then(t.bind(t,61716)),"@site/versioned_docs/version-1.4.0/archived_design/predicates.md",61716],"5bd52431":[()=>t.e(95309).then(t.bind(t,99398)),"@site/versioned_docs/version-1.3.0/design/scheduler_configuration.md",99398],"5c518724":[()=>t.e(53320).then(t.bind(t,12714)),"@site/versioned_docs/version-0.10.0/performance/metrics.md",12714],"5c9389cb":[()=>t.e(8765).then(t.bind(t,80429)),"@site/versioned_docs/version-0.12.1/get_started/core_features.md",80429],"5c9831a7":[()=>t.e(53716).then(t.bind(t,19530)),"@site/versioned_docs/version-0.12.1/design/scheduler_configuration.md",19530],"5c9ba668":[()=>t.e(57949).then(t.t.bind(t,17815,19)),"~docs/default/version-0-12-2-metadata-prop-2b6.json",17815],"5cf764b1":[()=>t.e(23819).then(t.bind(t,83124)),"@site/versioned_docs/version-1.2.0/user_guide/acls.md",83124],"5d439d21":[()=>t.e(18827).then(t.bind(t,67738)),"@site/versioned_docs/version-0.12.1/user_guide/workloads/run_spark.md",67738],"5d738820":[()=>t.e(5148).then(t.bind(t,39098)),"@site/versioned_docs/version-1.4.0/design/priority_scheduling.md",39098],"5df7ef96":[()=>t.e(62809).then(t.bind(t,5218)),"@site/versioned_docs/version-1.2.0/design/scheduler_plugin.md",5218],"5e906dfd":[()=>t.e(86618).then(t.bind(t,67610)),"@site/versioned_docs/version-0.12.1/performance/evaluate_perf_function_with_kubemark.md",67610],"5e9f5e1a":[()=>Promise.resolve().then(t.bind(t,4784)),"@generated/docusaurus.config",4784],"5eab74b1":[()=>t.e(82362).then(t.bind(t,44518)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/run_spark.md",44518],"605a9692":[()=>t.e(9763).then(t.bind(t,83385)),"@site/versioned_docs/version-0.12.1/design/resilience.md",83385],"6069883e":[()=>t.e(62270).then(t.bind(t,40678)),"@site/versioned_docs/version-1.3.0/user_guide/use_case.md",40678],"6175b9e3":[()=>t.e(79323).then(t.bind(t,15312)),"@site/versioned_docs/version-1.4.0/design/interface_message_simplification.md",15312],"617e9601":[()=>t.e(61980).then(t.bind(t,32839)),"@site/versioned_docs/version-1.5.0/developer_guide/build.md",32839],"6187a22c":[()=>t.e(8387).then(t.bind(t,72772)),"@site/versioned_docs/version-1.4.0/design/resilience.md",72772],"61e9bb6e":[()=>t.e(11429).then(t.bind(t,39831)),"@site/docs/user_guide/preemption.md",39831],"62cdd780":[()=>t.e(98601).then(t.bind(t,58600)),"@site/versioned_docs/version-1.1.0/user_guide/workloads/run_tensorflow.md",58600],"62e81aa6":[()=>t.e(80567).then(t.t.bind(t,23609,19)),"~docs/default/version-1-0-0-metadata-prop-608.json",23609],"6388662f":[()=>t.e(39038).then(t.bind(t,93820)),"@site/versioned_docs/version-1.4.0/user_guide/placement_rules.md",93820],"63d0f0e0":[()=>t.e(64915).then(t.bind(t,66070)),"@site/versioned_docs/version-0.12.1/design/scheduler_core_design.md",66070],"641fb5ab":[()=>t.e(52550).then(t.bind(t,85202)),"@site/versioned_docs/version-1.0.0/performance/metrics.md",85202],"6454a05b":[()=>t.e(59388).then(t.bind(t,81331)),"@site/src/pages/release-announce/1.0.0.md",81331],"648a3482":[()=>t.e(95851).then(t.bind(t,20607)),"@site/versioned_docs/version-1.2.0/performance/evaluate_perf_function_with_kubemark.md",20607],"649b7061":[()=>t.e(57618).then(t.bind(t,96522)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/run_mpi.md",96522],"64a11ff0":[()=>t.e(58356).then(t.bind(t,88449)),"@site/docs/design/architecture.md",88449],"6540f7c7":[()=>t.e(96443).then(t.bind(t,84455)),"@site/versioned_docs/version-0.10.0/user_guide/workloads/run_tensorflow.md",84455],"6561ff8a":[()=>t.e(83486).then(t.bind(t,20614)),"@site/versioned_docs/version-1.2.0/api/scheduler.md",20614],"65d34724":[()=>t.e(14338).then(t.bind(t,26630)),"@site/versioned_docs/version-0.12.2/performance/performance_tutorial.md",26630],"65e91a71":[()=>t.e(22152).then(t.bind(t,82831)),"@site/src/pages/release-announce/0.9.0.md",82831],66527541:[()=>t.e(83379).then(t.bind(t,10146)),"@site/versioned_docs/version-0.10.0/user_guide/acls.md",10146],"66d67008":[()=>t.e(11384).then(t.bind(t,70710)),"@site/versioned_docs/version-1.5.0/developer_guide/dependencies.md",70710],"67b585cb":[()=>t.e(67291).then(t.bind(t,81500)),"@site/versioned_docs/version-1.2.0/user_guide/usergroup_resolution.md",81500],"6875b121":[()=>t.e(13021).then(t.bind(t,69201)),"@site/versioned_docs/version-0.9.0/design/scheduler_configuration.md",69201],"68bfee64":[()=>t.e(77401).then(t.bind(t,98616)),"@site/src/pages/community/roadmap.md",98616],"6947aa75":[()=>t.e(4113).then(t.bind(t,98690)),"@site/versioned_docs/version-1.4.0/user_guide/resource_quota_mgmt.md",98690],"69994b68":[()=>t.e(91702).then(t.bind(t,24476)),"@site/versioned_docs/version-0.8.0/design/cross_queue_preemption.md",24476],"6a14e4a6":[()=>t.e(80097).then(t.bind(t,15285)),"@site/versioned_docs/version-0.12.1/performance/performance_tutorial.md",15285],"6a4d9186":[()=>t.e(74356).then(t.bind(t,87135)),"@site/versioned_docs/version-1.3.0/design/user_group_manager.md",87135],"6a858f16":[()=>t.e(75102).then(t.bind(t,21905)),"@site/versioned_docs/version-1.5.0/user_guide/acls.md",21905],"6abe350e":[()=>t.e(48190).then(t.bind(t,91741)),"@site/versioned_docs/version-1.3.0/design/scheduler_plugin.md",91741],"6b6cd41d":[()=>t.e(71013).then(t.bind(t,22889)),"@site/versioned_docs/version-0.9.0/get_started/get_started.md",22889],"6bb5aff3":[()=>t.e(33748).then(t.bind(t,37225)),"@site/docs/design/preemption.md",37225],"6bf8e8e6":[()=>t.e(13843).then(t.bind(t,54759)),"@site/docs/api/scheduler.md",54759],"6c36aa60":[()=>t.e(31425).then(t.bind(t,48396)),"@site/src/pages/community/get_involved.md",48396],"6d7a4f7b":[()=>t.e(35160).then(t.bind(t,17725)),"@site/versioned_docs/version-1.0.0/design/scheduler_configuration.md",17725],"6db854fa":[()=>t.e(90455).then(t.bind(t,84523)),"@site/versioned_docs/version-0.9.0/design/k8shim.md",84523],"6dd3a2f1":[()=>t.e(26112).then(t.bind(t,80192)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/run_spark.md",80192],"6e3154f7":[()=>t.e(37974).then(t.bind(t,65602)),"@site/docs/developer_guide/dependencies.md",65602],"6f0123ef":[()=>t.e(94530).then(t.bind(t,26819)),"@site/versioned_docs/version-1.3.0/design/user_group_handling.md",26819],"6f2f0c4c":[()=>t.e(18119).then(t.bind(t,90279)),"@site/versioned_docs/version-0.12.1/api/system.md",90279],70245927:[()=>t.e(23907).then(t.bind(t,92656)),"@site/src/pages/community/coding_guidelines.md",92656],"70f17b6a":[()=>t.e(96553).then(t.bind(t,61587)),"@site/versioned_docs/version-1.3.0/archived_design/predicates.md",61587],"719705af":[()=>t.e(74287).then(t.bind(t,30292)),"@site/versioned_docs/version-1.5.0/developer_guide/deployment.md",30292],72207194:[()=>t.e(40249).then(t.bind(t,95453)),"@site/versioned_docs/version-1.2.0/developer_guide/dependencies.md",95453],"730062b1":[()=>t.e(11506).then(t.bind(t,10988)),"@site/versioned_docs/version-1.3.0/user_guide/queue_config.md",10988],"74f9148b":[()=>t.e(95392).then(t.bind(t,24488)),"@site/versioned_docs/version-1.0.0/get_started/core_features.md",24488],"751b68b4":[()=>t.e(99746).then(t.bind(t,87718)),"@site/versioned_docs/version-0.12.1/design/scheduler_object_states.md",87718],"761be9ac":[()=>t.e(27083).then(t.bind(t,24589)),"@site/versioned_docs/version-0.10.0/user_guide/workloads/run_spark.md",24589],"76634d71":[()=>t.e(76709).then(t.bind(t,25661)),"@site/versioned_docs/version-0.12.2/user_guide/workloads/run_spark.md",25661],"77816f9e":[()=>t.e(38090).then(t.t.bind(t,62529,19)),"~docs/default/version-0-11-0-metadata-prop-434.json",62529],"785bbfee":[()=>t.e(81073).then(t.bind(t,87124)),"@site/versioned_docs/version-0.12.2/design/pluggable_app_management.md",87124],"78d8c6ce":[()=>t.e(6149).then(t.bind(t,13323)),"@site/versioned_docs/version-0.10.0/design/cross_queue_preemption.md",13323],"78e4148a":[()=>t.e(46571).then(t.bind(t,72411)),"@site/versioned_docs/version-1.3.0/design/preemption.md",72411],"794b0494":[()=>t.e(99222).then(t.bind(t,37542)),"@site/versioned_docs/version-0.12.2/user_guide/resource_quota_mgmt.md",37542],"79b08c73":[()=>t.e(59140).then(t.bind(t,35253)),"@site/versioned_docs/version-1.3.0/developer_guide/build.md",35253],"7b6b8da6":[()=>t.e(16061).then(t.bind(t,60371)),"@site/src/pages/community/release_procedure.md",60371],"7c3e0a90":[()=>t.e(40523).then(t.bind(t,14691)),"@site/versioned_docs/version-1.4.0/user_guide/deployment_modes.md",14691],"7c4de6ae":[()=>t.e(65038).then(t.bind(t,55985)),"@site/versioned_docs/version-0.11.0/user_guide/usergroup_resolution.md",55985],"7ce1a762":[()=>t.e(8919).then(t.bind(t,67337)),"@site/versioned_docs/version-1.0.0/user_guide/labels_and_annotations_in_yunikorn.md",67337],"7d04a98b":[()=>t.e(10394).then(t.bind(t,99800)),"@site/versioned_docs/version-1.2.0/performance/performance_tutorial.md",99800],"7ea12187":[()=>t.e(19293).then(t.bind(t,73977)),"@site/versioned_docs/version-1.5.0/user_guide/placement_rules.md",73977],"7fc5f702":[()=>t.e(33811).then(t.bind(t,25473)),"@site/versioned_docs/version-1.5.0/design/state_aware_scheduling.md",25473],"80348dae":[()=>t.e(22600).then(t.bind(t,45315)),"@site/docs/metrics/runtime.md",45315],"8102b5ac":[()=>t.e(15).then(t.bind(t,58104)),"@site/versioned_docs/version-0.12.1/developer_guide/env_setup.md",58104],"81215a04":[()=>t.e(21559).then(t.bind(t,88573)),"@site/versioned_docs/version-1.0.0/get_started/get_started.md",88573],"813c57df":[()=>t.e(58946).then(t.bind(t,71827)),"@site/versioned_docs/version-1.5.0/design/resilience.md",71827],"8199a7c1":[()=>t.e(28564).then(t.bind(t,8900)),"@site/versioned_docs/version-1.5.0/design/user_group_enforcement.md",8900],"829baac4":[()=>t.e(58755).then(t.bind(t,14570)),"@site/versioned_docs/version-1.4.0/user_guide/usergroup_resolution.md",14570],"830bde22":[()=>t.e(31087).then(t.bind(t,51751)),"@site/versioned_docs/version-0.8.0/design/pluggable_app_management.md",51751],"83debc9b":[()=>t.e(36253).then(t.bind(t,99420)),"@site/versioned_docs/version-1.1.0/performance/evaluate_perf_function_with_kubemark.md",99420],"83f9573b":[()=>t.e(26592).then(t.bind(t,68712)),"@site/versioned_docs/version-0.10.0/user_guide/placement_rules.md",68712],"842b9c6e":[()=>t.e(52072).then(t.bind(t,62246)),"@site/versioned_docs/version-0.10.0/design/state_aware_scheduling.md",62246],"850ece50":[()=>t.e(93936).then(t.bind(t,7877)),"@site/versioned_docs/version-0.11.0/performance/metrics.md",7877],"85f02d4b":[()=>t.e(49364).then(t.bind(t,98613)),"@site/versioned_docs/version-0.12.2/get_started/get_started.md",98613],"863d209f":[()=>t.e(92763).then(t.bind(t,96110)),"@site/versioned_docs/version-1.3.0/user_guide/gang_scheduling.md",96110],"872379cf":[()=>t.e(94246).then(t.bind(t,20340)),"@site/versioned_docs/version-0.8.0/setup/deployment.md",20340],"8745e5b0":[()=>t.e(98037).then(t.bind(t,9582)),"@site/versioned_docs/version-0.10.0/developer_guide/openshift_development.md",9582],"879025b0":[()=>t.e(77778).then(t.bind(t,23370)),"@site/versioned_docs/version-1.3.0/design/user_group_enforcement.md",23370],"883b80f5":[()=>t.e(49167).then(t.bind(t,62570)),"@site/versioned_docs/version-1.3.0/user_guide/deployment_modes.md",62570],"88ef04a7":[()=>t.e(43514).then(t.bind(t,83413)),"@site/versioned_docs/version-0.11.0/user_guide/trouble_shooting.md",83413],89522323:[()=>t.e(3299).then(t.bind(t,71886)),"@site/versioned_docs/version-1.5.0/design/gang_scheduling.md",71886],"89a0a60a":[()=>t.e(39545).then(t.bind(t,25054)),"@site/versioned_docs/version-1.0.0/performance/performance_tutorial.md",25054],"8a4daa3b":[()=>t.e(94155).then(t.bind(t,83735)),"@site/versioned_docs/version-1.1.0/design/scheduler_plugin.md",83735],"8a525f09":[()=>t.e(77671).then(t.bind(t,27084)),"@site/versioned_docs/version-1.4.0/archived_design/scheduler_core_design.md",27084],"8a6e3c59":[()=>t.e(99917).then(t.bind(t,72832)),"@site/versioned_docs/version-0.10.0/get_started/core_features.md",72832],"8aa5df97":[()=>t.e(52694).then(t.bind(t,21901)),"@site/versioned_docs/version-0.12.2/design/scheduler_core_design.md",21901],"8ac907f8":[()=>t.e(94979).then(t.bind(t,22983)),"@site/versioned_docs/version-0.12.2/api/cluster.md",22983],"8ad1c52d":[()=>t.e(31669).then(t.bind(t,93474)),"@site/versioned_docs/version-0.8.0/get_started/user_guide.md",93474],"8b190d09":[()=>t.e(33214).then(t.bind(t,38891)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/run_nvidia.md",38891],"8b608a5c":[()=>t.e(48866).then(t.bind(t,73750)),"@site/src/pages/release-announce/0.12.1.md",73750],"8bc280ca":[()=>t.e(79050).then(t.bind(t,93828)),"@site/versioned_docs/version-1.5.0/archived_design/namespace_resource_quota.md",93828],"8c9cae58":[()=>t.e(91857).then(t.bind(t,47288)),"@site/docs/archived_design/namespace_resource_quota.md",47288],"8d20ce23":[()=>t.e(62948).then(t.bind(t,531)),"@site/versioned_docs/version-0.12.1/performance/profiling.md",531],"8d2ab356":[()=>t.e(76120).then(t.bind(t,85733)),"@site/versioned_docs/version-0.10.0/get_started/get_started.md",85733],"8d971cbb":[()=>t.e(31255).then(t.bind(t,55976)),"@site/versioned_docs/version-1.5.0/performance/evaluate_perf_function_with_kubemark.md",55976],"8daebb13":[()=>t.e(24697).then(t.bind(t,78692)),"@site/versioned_docs/version-1.4.0/user_guide/sorting_policies.md",78692],"8daf2cfc":[()=>t.e(54838).then(t.bind(t,65290)),"@site/versioned_docs/version-1.4.0/design/config_v2.md",65290],"8e1bf126":[()=>t.e(95016).then(t.bind(t,4457)),"@site/docs/design/user_group_handling.md",4457],"8e403b22":[()=>t.e(35401).then(t.bind(t,33831)),"@site/versioned_docs/version-1.5.0/developer_guide/scheduler_object_states.md",33831],"8e7559bb":[()=>t.e(93120).then(t.bind(t,488)),"@site/versioned_docs/version-1.2.0/user_guide/workloads/run_flink.md",488],"8f5ca9a8":[()=>t.e(58764).then(t.bind(t,82045)),"@site/versioned_docs/version-0.10.0/design/scheduler_core_design.md",82045],"8f69be8c":[()=>t.e(83510).then(t.bind(t,52472)),"@site/versioned_docs/version-1.5.0/design/generic_resource.md",52472],"8fce5129":[()=>t.e(9508).then(t.bind(t,22472)),"@site/versioned_docs/version-0.10.0/design/resilience.md",22472],90571119:[()=>t.e(8248).then(t.bind(t,32596)),"@site/versioned_docs/version-1.2.0/developer_guide/openshift_development.md",32596],"915fdef3":[()=>t.e(40844).then(t.bind(t,38680)),"@site/versioned_docs/version-1.4.0/api/system.md",38680],"91d25720":[()=>t.e(43289).then(t.bind(t,48485)),"@site/versioned_docs/version-0.12.2/developer_guide/env_setup.md",48485],"92a19523":[()=>t.e(91467).then(t.bind(t,1891)),"@site/versioned_docs/version-0.8.0/design/resilience.md",1891],"92b7280d":[()=>t.e(59449).then(t.bind(t,37179)),"@site/versioned_docs/version-1.1.0/design/pluggable_app_management.md",37179],"92cca7ce":[()=>t.e(28104).then(t.bind(t,48738)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/run_flink.md",48738],"92d75d1c":[()=>t.e(37726).then(t.bind(t,4676)),"@site/versioned_docs/version-0.10.0/design/cache_removal.md",4676],"92ebcf1c":[()=>t.e(16308).then(t.bind(t,71507)),"@site/versioned_docs/version-1.1.0/user_guide/sorting_policies.md",71507],"935f2afb":[()=>t.e(98581).then(t.t.bind(t,35610,19)),"~docs/default/version-current-metadata-prop-751.json",35610],"93c6800a":[()=>t.e(42389).then(t.bind(t,66241)),"@site/versioned_docs/version-1.3.0/performance/performance_tutorial.md",66241],"93e59a16":[()=>t.e(48110).then(t.t.bind(t,5681,19)),"~docs/default/version-1-5-0-metadata-prop-eea.json",5681],"94abfae6":[()=>t.e(20515).then(t.bind(t,34832)),"@site/versioned_docs/version-1.5.0/get_started/version.md",34832],"94e4428c":[()=>t.e(3262).then(t.bind(t,12237)),"@site/versioned_docs/version-0.8.0/get_started/developer_guide.md",12237],"9523dcb5":[()=>t.e(53416).then(t.bind(t,42391)),"@site/versioned_docs/version-0.8.0/community/how_to_contribute.md",42391],"958e6623":[()=>t.e(51269).then(t.bind(t,79311)),"@site/docs/performance/performance_tutorial.md",79311],"959f8bcb":[()=>t.e(16325).then(t.bind(t,29691)),"@site/versioned_docs/version-1.1.0/get_started/core_features.md",29691],"95c50459":[()=>t.e(6507).then(t.bind(t,39185)),"@site/versioned_docs/version-1.3.0/user_guide/resource_quota_mgmt.md",39185],96225825:[()=>t.e(64818).then(t.bind(t,47549)),"@site/versioned_docs/version-1.2.0/api/cluster.md",47549],"9707d709":[()=>t.e(79798).then(t.bind(t,95032)),"@site/versioned_docs/version-0.8.0/performance/evaluate_perf_function_with_kubemark.md",95032],"9746ca7b":[()=>t.e(94526).then(t.bind(t,18418)),"@site/versioned_docs/version-1.2.0/archived_design/scheduler_core_design.md",18418],"9754eb65":[()=>t.e(97446).then(t.bind(t,25947)),"@site/versioned_docs/version-1.5.0/user_guide/preemption.md",25947],"97597cd7":[()=>t.e(88464).then(t.bind(t,56070)),"@site/versioned_docs/version-1.2.0/user_guide/sorting_policies.md",56070],"97cf841f":[()=>t.e(6249).then(t.bind(t,49494)),"@site/versioned_docs/version-1.3.0/archived_design/namespace_resource_quota.md",49494],"97ff1006":[()=>t.e(3926).then(t.bind(t,39703)),"@site/versioned_docs/version-1.5.0/user_guide/sorting_policies.md",39703],"9879f36f":[()=>t.e(25729).then(t.bind(t,25232)),"@site/versioned_docs/version-1.0.0/api/scheduler.md",25232],"988211ef":[()=>t.e(28153).then(t.bind(t,64525)),"@site/docs/archived_design/predicates.md",64525],"98bfff7a":[()=>t.e(81516).then(t.bind(t,58965)),"@site/versioned_docs/version-0.9.0/design/scheduler_object_states.md",58965],"98d35d14":[()=>t.e(45903).then(t.bind(t,87113)),"@site/versioned_docs/version-1.2.0/design/gang_scheduling.md",87113],"99e0db6b":[()=>t.e(43568).then(t.bind(t,54573)),"@site/versioned_docs/version-1.4.0/user_guide/troubleshooting.md",54573],"9a3fbf2b":[()=>t.e(76438).then(t.bind(t,42679)),"@site/docs/design/scheduler_plugin.md",42679],"9a6d52da":[()=>t.e(75751).then(t.t.bind(t,98274,19)),"~docs/default/version-0-9-0-metadata-prop-adb.json",98274],"9aa2d1d3":[()=>t.e(74146).then(t.bind(t,19939)),"@site/versioned_docs/version-1.1.0/api/cluster.md",19939],"9ce8caa5":[()=>t.e(74118).then(t.t.bind(t,27148,19)),"~docs/default/version-0-10-0-metadata-prop-94f.json",27148],"9e33764b":[()=>t.e(56802).then(t.bind(t,2960)),"@site/versioned_docs/version-1.5.0/performance/evaluate_perf_function_with_kwok.md",2960],"9e98946b":[()=>t.e(99441).then(t.bind(t,96510)),"@site/versioned_docs/version-1.5.0/get_started/get_started.md",96510],"9e9f5dce":[()=>t.e(32131).then(t.bind(t,59e3)),"@site/versioned_docs/version-0.9.0/design/pluggable_app_management.md",59e3],"9eea1548":[()=>t.e(56809).then(t.bind(t,22981)),"@site/versioned_docs/version-1.4.0/design/historical_usage_tracking.md",22981],"9f2f7e81":[()=>t.e(77007).then(t.bind(t,54479)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/workload_overview.md",54479],"9f72f8ad":[()=>t.e(65672).then(t.bind(t,60876)),"@site/versioned_docs/version-1.5.0/user_guide/troubleshooting.md",60876],"9f84576c":[()=>t.e(6595).then(t.bind(t,46278)),"@site/src/pages/release-announce/1.3.0.md",46278],a008f403:[()=>t.e(65473).then(t.bind(t,93679)),"@site/versioned_docs/version-1.0.0/design/gang_scheduling.md",93679],a05f508e:[()=>t.e(33707).then(t.bind(t,8553)),"@site/versioned_docs/version-1.4.0/archived_design/namespace_resource_quota.md",8553],a1c02285:[()=>t.e(16949).then(t.bind(t,84997)),"@site/versioned_docs/version-1.0.0/performance/profiling.md",84997],a252b33f:[()=>t.e(93669).then(t.bind(t,32091)),"@site/versioned_docs/version-1.5.0/design/interface_message_simplification.md",32091],a2c14f61:[()=>t.e(73235).then(t.bind(t,44164)),"@site/versioned_docs/version-1.4.0/api/scheduler.md",44164],a2c1c70a:[()=>t.e(78201).then(t.bind(t,44183)),"@site/versioned_docs/version-0.10.0/api/cluster.md",44183],a3304b48:[()=>t.e(95080).then(t.bind(t,31923)),"@site/versioned_docs/version-0.12.1/developer_guide/openshift_development.md",31923],a38fce19:[()=>t.e(67459).then(t.bind(t,31235)),"@site/versioned_docs/version-0.12.1/user_guide/acls.md",31235],a3cf9e9a:[()=>t.e(64476).then(t.bind(t,45299)),"@site/versioned_docs/version-1.2.0/user_guide/gang_scheduling.md",45299],a40e4d8d:[()=>t.e(11969).then(t.bind(t,50803)),"@site/versioned_docs/version-1.3.0/performance/metrics.md",50803],a4a95510:[()=>t.e(61895).then(t.bind(t,15433)),"@site/versioned_docs/version-0.9.0/performance/profiling.md",15433],a521008d:[()=>t.e(14774).then(t.bind(t,25626)),"@site/versioned_docs/version-1.3.0/design/scheduler_object_states.md",25626],a5b5dcea:[()=>t.e(5715).then(t.bind(t,71693)),"@site/versioned_docs/version-0.8.0/setup/configure_scheduler.md",71693],a5f90f12:[()=>t.e(3233).then(t.bind(t,77535)),"@site/versioned_docs/version-1.1.0/design/resilience.md",77535],a617c0b8:[()=>t.e(16341).then(t.bind(t,34896)),"@site/versioned_docs/version-0.12.2/get_started/core_features.md",34896],a633adf5:[()=>t.e(38600).then(t.bind(t,71125)),"@site/versioned_docs/version-1.4.0/user_guide/service_config.md",71125],a649354c:[()=>t.e(60912).then(t.bind(t,74218)),"@site/versioned_docs/version-1.0.0/user_guide/acls.md",74218],a6514927:[()=>t.e(56672).then(t.bind(t,21325)),"@site/docs/user_guide/placement_rules.md",21325],a65c2029:[()=>t.e(21187).then(t.bind(t,84617)),"@site/versioned_docs/version-1.0.0/design/scheduler_object_states.md",84617],a65edd96:[()=>t.e(69465).then(t.bind(t,20119)),"@site/versioned_docs/version-1.2.0/design/scheduler_object_states.md",20119],a6860501:[()=>t.e(26152).then(t.bind(t,29733)),"@site/versioned_docs/version-1.3.0/design/resilience.md",29733],a7022165:[()=>t.e(24045).then(t.bind(t,51255)),"@site/versioned_docs/version-0.12.1/design/cache_removal.md",51255],a75efafa:[()=>t.e(22773).then(t.bind(t,59956)),"@site/versioned_docs/version-0.9.0/design/resilience.md",59956],a77f4c3b:[()=>t.e(46484).then(t.bind(t,27018)),"@site/versioned_docs/version-1.1.0/user_guide/labels_and_annotations_in_yunikorn.md",27018],a7cd363d:[()=>t.e(52140).then(t.bind(t,97949)),"@site/versioned_docs/version-1.2.0/design/predicates.md",97949],a7fed74b:[()=>t.e(36645).then(t.bind(t,21909)),"@site/docs/user_guide/acls.md",21909],a8913000:[()=>t.e(73195).then(t.bind(t,85072)),"@site/versioned_docs/version-1.5.0/user_guide/deployment_modes.md",85072],a8d4abbe:[()=>t.e(92554).then(t.bind(t,1467)),"@site/versioned_docs/version-1.2.0/design/scheduler_core_design.md",1467],a8ec943f:[()=>t.e(70948).then(t.bind(t,16762)),"@site/versioned_docs/version-1.1.0/user_guide/workloads/workload_overview.md",16762],a9215700:[()=>t.e(85682).then(t.bind(t,56714)),"@site/versioned_docs/version-0.10.0/design/architecture.md",56714],a9bc95bb:[()=>t.e(34870).then(t.bind(t,62100)),"@site/versioned_docs/version-0.10.0/developer_guide/build.md",62100],aa222e6d:[()=>t.e(25308).then(t.bind(t,34096)),"@site/versioned_docs/version-1.3.0/user_guide/labels_and_annotations_in_yunikorn.md",34096],aa2738c3:[()=>t.e(92307).then(t.bind(t,74096)),"@site/versioned_docs/version-1.2.0/performance/metrics.md",74096],aa392378:[()=>t.e(71457).then(t.bind(t,11904)),"@site/docs/user_guide/gang_scheduling.md",11904],ac22c4de:[()=>t.e(58711).then(t.bind(t,21515)),"@site/docs/user_guide/workloads/run_flink.md",21515],ac710fda:[()=>t.e(42420).then(t.bind(t,27892)),"@site/versioned_docs/version-0.9.0/api/scheduler.md",27892],acc1e0c7:[()=>t.e(25042).then(t.bind(t,54919)),"@site/versioned_docs/version-1.0.0/user_guide/deployment_modes.md",54919],add37b26:[()=>t.e(28268).then(t.bind(t,8587)),"@site/versioned_docs/version-1.5.0/api/scheduler.md",8587],ae8ddf81:[()=>t.e(36814).then(t.bind(t,63180)),"@site/docs/user_guide/workloads/run_spark.md",63180],ae9f1acc:[()=>t.e(6524).then(t.bind(t,70289)),"@site/versioned_docs/version-1.1.0/design/simple_preemptor.md",70289],aea5966f:[()=>t.e(76786).then(t.bind(t,45628)),"@site/versioned_docs/version-0.11.0/design/k8shim.md",45628],aea8cccb:[()=>t.e(22819).then(t.bind(t,78092)),"@site/versioned_docs/version-1.0.0/developer_guide/build.md",78092],af25c48f:[()=>t.e(7402).then(t.bind(t,97015)),"@site/versioned_docs/version-0.12.1/performance/metrics.md",97015],af30bbb1:[()=>t.e(97988).then(t.bind(t,41020)),"@site/docs/performance/evaluate_perf_function_with_kwok.md",41020],afbdcc09:[()=>t.e(52891).then(t.bind(t,49693)),"@site/versioned_docs/version-1.0.0/user_guide/queue_config.md",49693],afe6f65e:[()=>t.e(35173).then(t.bind(t,74547)),"@site/docs/user_guide/sorting_policies.md",74547],afee9407:[()=>t.e(48900).then(t.bind(t,1162)),"@site/versioned_docs/version-1.4.0/design/user_group_manager.md",1162],b027356b:[()=>t.e(72420).then(t.bind(t,11229)),"@site/docs/archived_design/k8shim.md",11229],b06b747e:[()=>t.e(27504).then(t.bind(t,48782)),"@site/versioned_docs/version-0.10.0/design/namespace_resource_quota.md",48782],b0f84f31:[()=>t.e(40905).then(t.bind(t,76166)),"@site/versioned_docs/version-1.0.0/user_guide/workloads/run_flink.md",76166],b16939e2:[()=>t.e(60126).then(t.bind(t,52611)),"@site/versioned_docs/version-0.11.0/design/pluggable_app_management.md",52611],b198df35:[()=>t.e(78425).then(t.bind(t,28712)),"@site/versioned_docs/version-1.1.0/design/cross_queue_preemption.md",28712],b1c24be0:[()=>Promise.all([t.e(71869),t.e(33706)]).then(t.bind(t,16550)),"@site/src/pages/release-announce/index.js",16550],b2399376:[()=>t.e(55380).then(t.bind(t,85156)),"@site/docs/user_guide/use_case.md",85156],b2f441e1:[()=>t.e(6182).then(t.bind(t,31878)),"@site/versioned_docs/version-0.9.0/design/architecture.md",31878],b31cf73f:[()=>Promise.all([t.e(71869),t.e(70860)]).then(t.bind(t,79095)),"@site/versioned_docs/version-1.4.0/metrics/scheduler.mdx",79095],b56a9dad:[()=>t.e(83371).then(t.bind(t,52364)),"@site/versioned_docs/version-0.8.0/community/reporting_issues.md",52364],b695efd2:[()=>t.e(40742).then(t.bind(t,88344)),"@site/versioned_docs/version-0.12.2/user_guide/sorting_policies.md",88344],b6a19a2b:[()=>t.e(25263).then(t.bind(t,31597)),"@site/versioned_docs/version-1.1.0/user_guide/placement_rules.md",31597],b6ccfdca:[()=>t.e(70699).then(t.bind(t,70507)),"@site/versioned_docs/version-1.2.0/archived_design/namespace_resource_quota.md",70507],b780b841:[()=>t.e(70377).then(t.bind(t,80655)),"@site/src/pages/release-announce/1.4.0.md",80655],b8a75ff1:[()=>t.e(23075).then(t.bind(t,521)),"@site/versioned_docs/version-1.4.0/user_guide/queue_config.md",521],b8c87182:[()=>t.e(11866).then(t.bind(t,63953)),"@site/versioned_docs/version-0.9.0/design/scheduler_core_design.md",63953],b94a2346:[()=>t.e(80266).then(t.bind(t,15313)),"@site/versioned_docs/version-1.3.0/user_guide/sorting_policies.md",15313],b9526204:[()=>t.e(34473).then(t.t.bind(t,61966,19)),"/yunikorn-site/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",61966],b99ad014:[()=>t.e(15929).then(t.bind(t,17829)),"@site/versioned_docs/version-0.10.0/design/scheduler_configuration.md",17829],b9bde1e9:[()=>t.e(57426).then(t.bind(t,43592)),"@site/versioned_docs/version-1.2.0/design/namespace_resource_quota.md",43592],b9d8091f:[()=>t.e(63184).then(t.bind(t,97172)),"@site/versioned_docs/version-1.4.0/metrics/runtime.md",97172],bb9c3ed9:[()=>t.e(53754).then(t.bind(t,41044)),"@site/versioned_docs/version-0.11.0/design/scheduler_core_design.md",41044],bb9f8df1:[()=>t.e(46765).then(t.bind(t,7497)),"@site/versioned_docs/version-1.1.0/design/namespace_resource_quota.md",7497],bcca5012:[()=>t.e(51068).then(t.bind(t,94647)),"@site/versioned_docs/version-1.1.0/user_guide/resource_quota_mgmt.md",94647],bce28ad4:[()=>t.e(72406).then(t.bind(t,5409)),"@site/versioned_docs/version-1.5.0/performance/metrics.md",5409],bd0b3be5:[()=>t.e(64078).then(t.bind(t,30891)),"@site/versioned_docs/version-1.3.0/design/simple_preemptor.md",30891],bd59b609:[()=>t.e(90046).then(t.bind(t,83617)),"@site/versioned_docs/version-1.4.0/developer_guide/deployment.md",83617],bd9c2ce3:[()=>t.e(56176).then(t.bind(t,41170)),"@site/versioned_docs/version-1.4.0/performance/performance_tutorial.md",41170],be46464e:[()=>t.e(17785).then(t.bind(t,69732)),"@site/versioned_docs/version-0.12.2/developer_guide/build.md",69732],be6859b2:[()=>t.e(37404).then(t.bind(t,20512)),"@site/versioned_docs/version-1.1.0/developer_guide/build.md",20512],be7a0dbe:[()=>t.e(57387).then(t.bind(t,76978)),"@site/versioned_docs/version-1.1.0/get_started/get_started.md",76978],bebf10ba:[()=>t.e(51200).then(t.bind(t,91582)),"@site/versioned_docs/version-0.9.0/developer_guide/deployment.md",91582],bf59ca81:[()=>t.e(7420).then(t.bind(t,47138)),"@site/versioned_docs/version-1.1.0/user_guide/queue_config.md",47138],bff552dd:[()=>t.e(6669).then(t.bind(t,11325)),"@site/versioned_docs/version-1.0.0/developer_guide/deployment.md",11325],c0390a80:[()=>t.e(4047).then(t.bind(t,9281)),"@site/versioned_docs/version-1.3.0/design/pluggable_app_management.md",9281],c07122e1:[()=>t.e(67148).then(t.bind(t,96543)),"@site/versioned_docs/version-0.10.0/design/k8shim.md",96543],c0873f99:[()=>t.e(7180).then(t.bind(t,62326)),"@site/versioned_docs/version-1.4.0/design/architecture.md",62326],c08d65fc:[()=>t.e(43948).then(t.bind(t,95753)),"@site/versioned_docs/version-1.5.0/archived_design/k8shim.md",95753],c0a49dd7:[()=>t.e(32209).then(t.bind(t,61322)),"@site/versioned_docs/version-0.11.0/user_guide/queue_config.md",61322],c0bd6a4b:[()=>t.e(58133).then(t.bind(t,75083)),"@site/versioned_docs/version-1.2.0/developer_guide/env_setup.md",75083],c140d46c:[()=>t.e(50794).then(t.bind(t,89211)),"@site/versioned_docs/version-0.11.0/developer_guide/build.md",89211],c1be4069:[()=>t.e(80715).then(t.bind(t,78556)),"@site/docs/metrics/queue.md",78556],c1d1596b:[()=>t.e(18340).then(t.bind(t,24921)),"@site/versioned_docs/version-0.11.0/developer_guide/openshift_development.md",24921],c2467954:[()=>t.e(75397).then(t.bind(t,34474)),"@site/versioned_docs/version-0.12.1/api/cluster.md",34474],c25457d3:[()=>t.e(44556).then(t.bind(t,9504)),"@site/versioned_docs/version-1.0.0/design/resilience.md",9504],c3a3eb3c:[()=>t.e(70294).then(t.bind(t,58203)),"@site/versioned_docs/version-1.4.0/archived_design/pluggable_app_management.md",58203],c3b79105:[()=>t.e(27683).then(t.bind(t,42788)),"@site/versioned_docs/version-0.9.0/get_started/core_features.md",42788],c3dff334:[()=>t.e(55991).then(t.bind(t,2832)),"@site/docs/api/cluster.md",2832],c3efefe4:[()=>t.e(93474).then(t.bind(t,33709)),"@site/versioned_docs/version-1.0.0/developer_guide/env_setup.md",33709],c452b0b7:[()=>t.e(28768).then(t.bind(t,71508)),"@site/versioned_docs/version-1.1.0/user_guide/deployment_modes.md",71508],c4f5d8e4:[()=>Promise.all([t.e(71869),t.e(52634)]).then(t.bind(t,81700)),"@site/src/pages/index.js",81700],c512952f:[()=>t.e(66564).then(t.bind(t,48217)),"@site/versioned_docs/version-0.12.1/api/scheduler.md",48217],c52cb584:[()=>t.e(17369).then(t.bind(t,20741)),"@site/versioned_docs/version-1.0.0/performance/evaluate_perf_function_with_kubemark.md",20741],c56532b8:[()=>t.e(73509).then(t.bind(t,89221)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/run_nvidia.md",89221],c610c5a8:[()=>t.e(92052).then(t.bind(t,89532)),"@site/versioned_docs/version-1.0.0/api/system.md",89532],c6405911:[()=>t.e(26480).then(t.bind(t,90225)),"@site/versioned_docs/version-0.9.0/developer_guide/env_setup.md",90225],c65b3d63:[()=>t.e(31245).then(t.bind(t,31253)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/run_flink.md",31253],c70aa1ed:[()=>t.e(53409).then(t.bind(t,63343)),"@site/versioned_docs/version-1.3.0/design/architecture.md",63343],c7277ad6:[()=>t.e(37310).then(t.bind(t,29940)),"@site/versioned_docs/version-0.8.0/community/community_sync_up.md",29940],c78cff6c:[()=>t.e(46067).then(t.bind(t,17033)),"@site/docs/archived_design/cross_queue_preemption.md",17033],c7eff138:[()=>t.e(35230).then(t.bind(t,27614)),"@site/versioned_docs/version-1.3.0/api/cluster.md",27614],c8855521:[()=>t.e(3302).then(t.bind(t,21312)),"@site/versioned_docs/version-1.2.0/design/architecture.md",21312],c8ec7de9:[()=>t.e(58705).then(t.bind(t,47194)),"@site/docs/user_guide/workloads/workload_overview.md",47194],c928173c:[()=>t.e(42683).then(t.bind(t,18373)),"@site/versioned_docs/version-0.10.0/developer_guide/deployment.md",18373],c95b781b:[()=>t.e(12726).then(t.t.bind(t,34912,19)),"~docs/default/version-0-8-0-metadata-prop-466.json",34912],c9bc13ce:[()=>t.e(75566).then(t.bind(t,86161)),"@site/versioned_docs/version-0.11.0/design/namespace_resource_quota.md",86161],ca3ac135:[()=>t.e(55067).then(t.bind(t,92107)),"@site/versioned_docs/version-1.5.0/user_guide/resource_quota_mgmt.md",92107],ca87bd6e:[()=>t.e(56601).then(t.bind(t,47776)),"@site/versioned_docs/version-0.11.0/user_guide/workloads/run_tensorflow.md",47776],cacb3d65:[()=>t.e(38634).then(t.bind(t,67556)),"@site/versioned_docs/version-0.11.0/user_guide/workloads/run_spark.md",67556],cb2f5335:[()=>t.e(89760).then(t.bind(t,92615)),"@site/versioned_docs/version-1.3.0/user_guide/usergroup_resolution.md",92615],cb5e20e2:[()=>t.e(99377).then(t.bind(t,40076)),"@site/versioned_docs/version-1.1.0/user_guide/workloads/run_spark.md",40076],cbc12d17:[()=>t.e(90442).then(t.bind(t,68662)),"@site/versioned_docs/version-0.10.0/user_guide/resource_quota_mgmt.md",68662],cc3eb85c:[()=>t.e(30563).then(t.bind(t,13555)),"@site/versioned_docs/version-1.0.0/user_guide/sorting_policies.md",13555],cd72eb9e:[()=>t.e(33386).then(t.bind(t,40385)),"@site/versioned_docs/version-1.3.0/design/priority_scheduling.md",40385],cd78c8cb:[()=>t.e(75853).then(t.bind(t,12221)),"@site/versioned_docs/version-1.5.0/design/user_group_handling.md",12221],cd8a45a6:[()=>t.e(30079).then(t.bind(t,88071)),"@site/versioned_docs/version-1.2.0/user_guide/labels_and_annotations_in_yunikorn.md",88071],cd9d94be:[()=>t.e(34221).then(t.bind(t,41023)),"@site/versioned_docs/version-1.4.0/design/generic_resource.md",41023],ce30221e:[()=>t.e(36852).then(t.bind(t,89212)),"@site/docs/user_guide/priorities.md",89212],ce784664:[()=>t.e(16626).then(t.bind(t,57082)),"@site/versioned_docs/version-0.11.0/get_started/get_started.md",57082],ce9e2dcf:[()=>t.e(2932).then(t.bind(t,21954)),"@site/versioned_docs/version-0.9.0/design/state_aware_scheduling.md",21954],cf5a4cff:[()=>t.e(82413).then(t.bind(t,71688)),"@site/versioned_docs/version-1.4.0/design/cache_removal.md",71688],cf736a7b:[()=>t.e(38622).then(t.bind(t,23699)),"@site/versioned_docs/version-1.0.0/design/cross_queue_preemption.md",23699],cfabf7e9:[()=>t.e(45738).then(t.bind(t,67271)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/run_mpi.md",67271],cff1c286:[()=>t.e(55526).then(t.bind(t,54079)),"@site/versioned_docs/version-1.4.0/design/user_group_enforcement.md",54079],d063fe9f:[()=>t.e(23016).then(t.bind(t,74595)),"@site/versioned_docs/version-1.5.0/design/scheduler_plugin.md",74595],d0cc8b4f:[()=>t.e(46069).then(t.bind(t,21367)),"@site/versioned_docs/version-1.2.0/get_started/get_started.md",21367],d1187d43:[()=>t.e(12515).then(t.bind(t,31387)),"@site/versioned_docs/version-1.4.0/user_guide/workloads/run_tensorflow.md",31387],d15d046b:[()=>t.e(18181).then(t.bind(t,14478)),"@site/docs/user_guide/workloads/run_nvidia.md",14478],d16572ac:[()=>t.e(1038).then(t.bind(t,25248)),"@site/versioned_docs/version-1.0.0/user_guide/placement_rules.md",25248],d248ca85:[()=>t.e(98808).then(t.bind(t,73938)),"@site/versioned_docs/version-1.2.0/user_guide/placement_rules.md",73938],d28f8723:[()=>t.e(35581).then(t.bind(t,11701)),"@site/versioned_docs/version-0.12.2/user_guide/gang_scheduling.md",11701],d3b31caa:[()=>t.e(17303).then(t.bind(t,73297)),"@site/versioned_docs/version-1.1.0/design/cache_removal.md",73297],d3bbc5fd:[()=>t.e(9790).then(t.bind(t,9016)),"@site/versioned_docs/version-0.11.0/developer_guide/deployment.md",9016],d443b36e:[()=>t.e(19662).then(t.bind(t,5886)),"@site/versioned_docs/version-0.11.0/developer_guide/env_setup.md",5886],d4751fcb:[()=>t.e(15889).then(t.bind(t,2854)),"@site/versioned_docs/version-1.4.0/user_guide/acls.md",2854],d4cdbb95:[()=>t.e(22408).then(t.bind(t,76676)),"@site/versioned_docs/version-0.11.0/performance/evaluate_perf_function_with_kubemark.md",76676],d4e92657:[()=>t.e(52153).then(t.bind(t,5540)),"@site/versioned_docs/version-0.10.0/api/system.md",5540],d5f4f3d4:[()=>t.e(32961).then(t.bind(t,77200)),"@site/versioned_docs/version-0.9.0/developer_guide/build.md",77200],d643cbaf:[()=>t.e(82756).then(t.bind(t,27996)),"@site/versioned_docs/version-1.0.0/design/pluggable_app_management.md",27996],d6ce4507:[()=>t.e(77039).then(t.bind(t,47499)),"@site/versioned_docs/version-1.1.0/user_guide/workloads/run_flink.md",47499],d77c210f:[()=>t.e(78187).then(t.bind(t,8969)),"@site/versioned_docs/version-1.4.0/user_guide/gang_scheduling.md",8969],d7cf88d1:[()=>Promise.all([t.e(71869),t.e(33270)]).then(t.bind(t,5550)),"@site/docs/metrics/scheduler.mdx",5550],d808852d:[()=>t.e(76108).then(t.bind(t,40915)),"@site/versioned_docs/version-0.11.0/get_started/core_features.md",40915],d84189a7:[()=>t.e(78763).then(t.bind(t,84267)),"@site/versioned_docs/version-0.9.0/user_guide/workloads/run_tensorflow.md",84267],d8538008:[()=>t.e(9895).then(t.bind(t,87295)),"@site/versioned_docs/version-0.12.1/user_guide/trouble_shooting.md",87295],d872d333:[()=>t.e(61601).then(t.bind(t,26981)),"@site/versioned_docs/version-0.11.0/design/state_aware_scheduling.md",26981],d8aa108f:[()=>t.e(95656).then(t.bind(t,51019)),"@site/versioned_docs/version-1.2.0/performance/profiling.md",51019],d8ac4d11:[()=>t.e(353).then(t.bind(t,85736)),"@site/versioned_docs/version-0.10.0/user_guide/sorting_policies.md",85736],d9f7e22f:[()=>t.e(91554).then(t.bind(t,99850)),"@site/versioned_docs/version-1.1.0/design/gang_scheduling.md",99850],da3e9658:[()=>t.e(51308).then(t.bind(t,2536)),"@site/versioned_docs/version-0.8.0/design/design.md",2536],da4a45a6:[()=>t.e(3735).then(t.bind(t,37640)),"@site/versioned_docs/version-1.5.0/design/scheduler_configuration.md",37640],da845f06:[()=>t.e(33261).then(t.bind(t,68419)),"@site/versioned_docs/version-1.0.0/design/predicates.md",68419],da84cc0d:[()=>t.e(2652).then(t.bind(t,68752)),"@site/docs/developer_guide/deployment.md",68752],daba4570:[()=>t.e(49409).then(t.bind(t,39272)),"@site/versioned_docs/version-0.10.0/api/scheduler.md",39272],dadaae3f:[()=>t.e(88542).then(t.bind(t,3286)),"@site/versioned_docs/version-1.1.0/developer_guide/env_setup.md",3286],db881351:[()=>t.e(34463).then(t.bind(t,38296)),"@site/versioned_docs/version-1.3.0/user_guide/workloads/run_nvidia.md",38296],db9c64ed:[()=>t.e(13940).then(t.bind(t,4655)),"@site/versioned_docs/version-1.2.0/developer_guide/deployment.md",4655],dbb33cef:[()=>t.e(45071).then(t.bind(t,12293)),"@site/versioned_docs/version-0.12.1/user_guide/resource_quota_mgmt.md",12293],dbbae471:[()=>t.e(61145).then(t.bind(t,20181)),"@site/versioned_docs/version-1.2.0/user_guide/deployment_modes.md",20181],dc8253a3:[()=>t.e(78678).then(t.bind(t,36522)),"@site/versioned_docs/version-0.12.1/design/predicates.md",36522],dcb5266f:[()=>t.e(2647).then(t.bind(t,7384)),"@site/versioned_docs/version-1.5.0/design/historical_usage_tracking.md",7384],de8ad7db:[()=>t.e(59682).then(t.bind(t,62168)),"@site/versioned_docs/version-0.12.2/api/scheduler.md",62168],deaca5dd:[()=>t.e(24288).then(t.bind(t,91291)),"@site/versioned_docs/version-0.11.0/user_guide/sorting_policies.md",91291],debcf1ca:[()=>t.e(63588).then(t.bind(t,70363)),"@site/versioned_docs/version-0.8.0/configuration/acls.md",70363],deedc2a8:[()=>t.e(26133).then(t.bind(t,8149)),"@site/versioned_docs/version-1.0.0/user_guide/workloads/run_spark.md",8149],df632275:[()=>t.e(34412).then(t.bind(t,68978)),"@site/versioned_docs/version-1.2.0/archived_design/k8shim.md",68978],df6ab4bc:[()=>t.e(82669).then(t.bind(t,81196)),"@site/versioned_docs/version-0.11.0/design/scheduler_object_states.md",81196],dfc96154:[()=>t.e(24165).then(t.bind(t,45907)),"@site/versioned_docs/version-1.2.0/user_guide/service_config.md",45907],e0250fe6:[()=>t.e(21600).then(t.bind(t,24922)),"@site/versioned_docs/version-1.4.0/design/simple_preemptor.md",24922],e0cfa6fb:[()=>t.e(48098).then(t.bind(t,91940)),"@site/versioned_docs/version-1.4.0/archived_design/k8shim.md",91940],e0ea7e73:[()=>t.e(86048).then(t.bind(t,436)),"@site/docs/get_started/version.md",436],e127b1c1:[()=>t.e(85775).then(t.bind(t,19557)),"@site/versioned_docs/version-1.4.0/user_guide/labels_and_annotations_in_yunikorn.md",19557],e15bcb33:[()=>t.e(71453).then(t.t.bind(t,51479,19)),"~docs/default/version-1-1-0-metadata-prop-2f9.json",51479],e2561c05:[()=>t.e(67546).then(t.bind(t,75126)),"@site/docs/developer_guide/env_setup.md",75126],e2e6c14f:[()=>t.e(64705).then(t.bind(t,93022)),"@site/versioned_docs/version-0.12.2/developer_guide/openshift_development.md",93022],e30960a7:[()=>t.e(95316).then(t.bind(t,57904)),"@site/versioned_docs/version-1.3.0/user_guide/service_config.md",57904],e36c389f:[()=>t.e(83430).then(t.bind(t,40673)),"@site/versioned_docs/version-1.1.0/developer_guide/openshift_development.md",40673],e3883bac:[()=>t.e(88852).then(t.bind(t,95011)),"@site/versioned_docs/version-0.12.1/design/architecture.md",95011],e3e676f7:[()=>t.e(67228).then(t.bind(t,56271)),"@site/versioned_docs/version-1.0.0/api/cluster.md",56271],e59213c0:[()=>t.e(58465).then(t.bind(t,50065)),"@site/versioned_docs/version-0.8.0/performance/metrics.md",50065],e5e048c5:[()=>t.e(58250).then(t.bind(t,38961)),"@site/docs/design/cache_removal.md",38961],e62294b1:[()=>t.e(76842).then(t.bind(t,52494)),"@site/versioned_docs/version-1.2.0/design/user_group_handling.md",52494],e6aabe98:[()=>t.e(87392).then(t.bind(t,99788)),"@site/versioned_docs/version-0.11.0/design/scheduler_configuration.md",99788],e6f1bbf8:[()=>t.e(97555).then(t.bind(t,8933)),"@site/versioned_docs/version-0.10.0/user_guide/gang_scheduling.md",8933],e718b7e6:[()=>t.e(24944).then(t.bind(t,3441)),"@site/docs/user_guide/workloads/run_mpi.md",3441],e74fe2a7:[()=>t.e(41880).then(t.bind(t,70016)),"@site/versioned_docs/version-1.4.0/developer_guide/build.md",70016],e75f0651:[()=>t.e(33070).then(t.bind(t,71576)),"@site/versioned_docs/version-1.2.0/design/state_aware_scheduling.md",71576],e7752ddb:[()=>t.e(60491).then(t.bind(t,36900)),"@site/versioned_docs/version-1.3.0/developer_guide/env_setup.md",36900],e7c63a3c:[()=>t.e(85958).then(t.bind(t,43061)),"@site/versioned_docs/version-0.12.1/user_guide/sorting_policies.md",43061],e80a80ce:[()=>t.e(9669).then(t.bind(t,33943)),"@site/docs/design/interface_message_simplification.md",33943],e897f185:[()=>t.e(8250).then(t.bind(t,39269)),"@site/docs/api/system.md",39269],e8ce8f9a:[()=>t.e(68596).then(t.bind(t,24461)),"@site/versioned_docs/version-1.1.0/performance/metrics.md",24461],e91b02be:[()=>t.e(93637).then(t.bind(t,71466)),"@site/docs/user_guide/labels_and_annotations_in_yunikorn.md",71466],e9498790:[()=>t.e(29976).then(t.bind(t,14637)),"@site/versioned_docs/version-0.10.0/performance/evaluate_perf_function_with_kubemark.md",14637],e951bf48:[()=>t.e(26155).then(t.bind(t,93054)),"@site/versioned_docs/version-1.0.0/user_guide/usergroup_resolution.md",93054],ead72281:[()=>t.e(69999).then(t.bind(t,64694)),"@site/versioned_docs/version-0.9.0/user_guide/acls.md",64694],eb39d40e:[()=>t.e(16939).then(t.bind(t,18447)),"@site/versioned_docs/version-1.2.0/user_guide/queue_config.md",18447],ebb6a828:[()=>t.e(12791).then(t.bind(t,49076)),"@site/versioned_docs/version-1.1.0/design/scheduler_object_states.md",49076],ec5ce2a8:[()=>t.e(10853).then(t.bind(t,38354)),"@site/versioned_docs/version-1.4.0/design/state_aware_scheduling.md",38354],ed0bdba3:[()=>t.e(91136).then(t.bind(t,90261)),"@site/versioned_docs/version-1.5.0/design/user_group_manager.md",90261],ed3bee84:[()=>t.e(43169).then(t.bind(t,50971)),"@site/docs/get_started/core_features.md",50971],ed701816:[()=>t.e(82175).then(t.bind(t,9716)),"@site/versioned_docs/version-1.1.0/design/generic_resource.md",9716],efa2f5a1:[()=>t.e(81874).then(t.bind(t,68821)),"@site/versioned_docs/version-0.11.0/user_guide/placement_rules.md",68821],efe1d13a:[()=>t.e(94433).then(t.bind(t,77751)),"@site/versioned_docs/version-0.12.2/design/gang_scheduling.md",77751],f0045c87:[()=>t.e(22442).then(t.bind(t,39774)),"@site/docs/user_guide/service_config.md",39774],f03fab11:[()=>t.e(37681).then(t.bind(t,58922)),"@site/versioned_docs/version-0.12.1/design/cross_queue_preemption.md",58922],f12e5031:[()=>t.e(81044).then(t.bind(t,42775)),"@site/docs/user_guide/resource_quota_mgmt.md",42775],f14a91aa:[()=>t.e(65441).then(t.bind(t,41244)),"@site/versioned_docs/version-1.5.0/user_guide/gang_scheduling.md",41244],f17eea78:[()=>t.e(12031).then(t.bind(t,4512)),"@site/versioned_docs/version-1.4.0/design/scheduler_plugin.md",4512],f1bf9ead:[()=>t.e(53045).then(t.bind(t,93002)),"@site/versioned_docs/version-0.12.1/user_guide/gang_scheduling.md",93002],f31b0025:[()=>t.e(12032).then(t.bind(t,25583)),"@site/src/pages/release-announce/0.12.2.md",25583],f3634bd2:[()=>t.e(95315).then(t.bind(t,70293)),"@site/versioned_docs/version-1.0.0/design/scheduler_core_design.md",70293],f3be527a:[()=>t.e(86164).then(t.bind(t,86058)),"@site/versioned_docs/version-1.2.0/api/system.md",86058],f5272822:[()=>t.e(54727).then(t.bind(t,37538)),"@site/versioned_docs/version-0.12.2/user_guide/trouble_shooting.md",37538],f63c7767:[()=>t.e(18122).then(t.bind(t,95601)),"@site/versioned_docs/version-1.3.0/get_started/core_features.md",95601],f6435ed1:[()=>t.e(45087).then(t.bind(t,45363)),"@site/docs/developer_guide/build.md",45363],f6d558f6:[()=>t.e(39221).then(t.bind(t,73444)),"@site/versioned_docs/version-1.1.0/design/k8shim.md",73444],f769181d:[()=>t.e(40081).then(t.bind(t,41618)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/run_nvidia.md",41618],f7c05237:[()=>t.e(6428).then(t.bind(t,94109)),"@site/src/pages/community/reporting_issues.md",94109],f7f2e981:[()=>t.e(9197).then(t.bind(t,25500)),"@site/versioned_docs/version-1.3.0/design/gang_scheduling.md",25500],f8b6f1ce:[()=>t.e(5874).then(t.bind(t,30827)),"@site/docs/archived_design/scheduler_core_design.md",30827],f933782b:[()=>t.e(2075).then(t.bind(t,70325)),"@site/versioned_docs/version-0.12.2/developer_guide/deployment.md",70325],f9faa05a:[()=>t.e(20118).then(t.bind(t,15741)),"@site/versioned_docs/version-1.5.0/developer_guide/openshift_development.md",15741],fa9bdbac:[()=>t.e(22343).then(t.t.bind(t,90733,19)),"~docs/default/version-1-4-0-metadata-prop-a65.json",90733],facbb56d:[()=>t.e(37802).then(t.bind(t,87806)),"@site/versioned_docs/version-1.2.0/design/resilience.md",87806],fadff26c:[()=>t.e(26091).then(t.bind(t,98256)),"@site/versioned_docs/version-1.4.0/design/user_group_handling.md",98256],fafbe599:[()=>t.e(61076).then(t.bind(t,62849)),"@site/versioned_docs/version-1.5.0/archived_design/predicates.md",62849],fb133e19:[()=>t.e(70273).then(t.bind(t,66815)),"@site/versioned_docs/version-0.9.0/design/predicates.md",66815],fc009b8f:[()=>t.e(7545).then(t.bind(t,43693)),"@site/versioned_docs/version-0.11.0/user_guide/acls.md",43693],fc3648c4:[()=>t.e(26328).then(t.bind(t,38582)),"@site/versioned_docs/version-1.0.0/developer_guide/openshift_development.md",38582],fc9493b5:[()=>t.e(86650).then(t.bind(t,36109)),"@site/versioned_docs/version-1.5.0/user_guide/workloads/run_mpi.md",36109],fd2b2a05:[()=>t.e(22483).then(t.bind(t,2267)),"@site/versioned_docs/version-1.4.0/user_guide/prometheus.md",2267],fd3398f1:[()=>t.e(72903).then(t.bind(t,9759)),"@site/docs/design/resilience.md",9759],fd8e5d2f:[()=>t.e(52335).then(t.bind(t,26714)),"@site/docs/archived_design/pluggable_app_management.md",26714],fea909d2:[()=>t.e(19393).then(t.bind(t,41164)),"@site/versioned_docs/version-1.5.0/api/cluster.md",41164]};function d(e){let{error:n,retry:t,pastDelay:r}=e;return n?o.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},o.createElement("p",null,String(n)),o.createElement("div",null,o.createElement("button",{type:"button",onClick:t},"Retry"))):r?o.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},o.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},o.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},o.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},o.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),o.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},o.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),o.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),o.createElement("circle",{cx:"22",cy:"22",r:"8"},o.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=t(44404),l=t(86131);function p(e,n){if("*"===e)return i()({loading:d,loader:()=>t.e(9850).then(t.bind(t,9850)),modules:["@theme/NotFound"],webpack:()=>[9850],render(e,n){const t=e.default;return o.createElement(l.W,{value:{plugin:{name:"native",id:"default"}}},o.createElement(t,n))}});const s=a[e+"-"+n],p={},g=[],m=[],_=(0,u.A)(s);return Object.entries(_).forEach((e=>{let[n,t]=e;const o=c[t];o&&(p[n]=o[0],g.push(o[1]),m.push(o[2]))})),i().Map({loading:d,loader:p,modules:g,webpack:()=>m,render(n,t){const i=JSON.parse(JSON.stringify(s));Object.entries(n).forEach((n=>{let[t,o]=n;const r=o.default;if(!r)throw new Error("The page component at "+e+" doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.");"object"!=typeof r&&"function"!=typeof r||Object.keys(o).filter((e=>"default"!==e)).forEach((e=>{r[e]=o[e]}));let s=i;const a=t.split(".");a.slice(0,-1).forEach((e=>{s=s[e]})),s[a[a.length-1]]=r}));const a=i.__comp;delete i.__comp;const c=i.__context;return delete i.__context,o.createElement(l.W,{value:c},o.createElement(a,(0,r.A)({},i,t)))}})}const g=[{path:"/community/",component:p("/community/","f31"),exact:!0},{path:"/community/coding_guidelines",component:p("/community/coding_guidelines","e79"),exact:!0},{path:"/community/download",component:p("/community/download","a22"),exact:!0},{path:"/community/events",component:p("/community/events","082"),exact:!0},{path:"/community/get_involved",component:p("/community/get_involved","984"),exact:!0},{path:"/community/how_to_contribute",component:p("/community/how_to_contribute","a9e"),exact:!0},{path:"/community/people",component:p("/community/people","b53"),exact:!0},{path:"/community/release_procedure",component:p("/community/release_procedure","665"),exact:!0},{path:"/community/reporting_issues",component:p("/community/reporting_issues","452"),exact:!0},{path:"/community/roadmap",component:p("/community/roadmap","a90"),exact:!0},{path:"/release-announce/",component:p("/release-announce/","e3e"),exact:!0},{path:"/release-announce/0.10.0",component:p("/release-announce/0.10.0","414"),exact:!0},{path:"/release-announce/0.11.0",component:p("/release-announce/0.11.0","3cb"),exact:!0},{path:"/release-announce/0.12.1",component:p("/release-announce/0.12.1","581"),exact:!0},{path:"/release-announce/0.12.2",component:p("/release-announce/0.12.2","ebb"),exact:!0},{path:"/release-announce/0.8.0",component:p("/release-announce/0.8.0","15c"),exact:!0},{path:"/release-announce/0.9.0",component:p("/release-announce/0.9.0","1dc"),exact:!0},{path:"/release-announce/1.0.0",component:p("/release-announce/1.0.0","543"),exact:!0},{path:"/release-announce/1.1.0",component:p("/release-announce/1.1.0","2f3"),exact:!0},{path:"/release-announce/1.2.0",component:p("/release-announce/1.2.0","a96"),exact:!0},{path:"/release-announce/1.3.0",component:p("/release-announce/1.3.0","143"),exact:!0},{path:"/release-announce/1.4.0",component:p("/release-announce/1.4.0","b4f"),exact:!0},{path:"/release-announce/1.5.0",component:p("/release-announce/1.5.0","435"),exact:!0},{path:"/search",component:p("/search","f6c"),exact:!0},{path:"/docs/0.10.0",component:p("/docs/0.10.0","393"),routes:[{path:"/docs/0.10.0/",component:p("/docs/0.10.0/","628"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/api/cluster",component:p("/docs/0.10.0/api/cluster","377"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/api/scheduler",component:p("/docs/0.10.0/api/scheduler","775"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/api/system",component:p("/docs/0.10.0/api/system","464"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/architecture",component:p("/docs/0.10.0/design/architecture","b69"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/cache_removal",component:p("/docs/0.10.0/design/cache_removal","e90"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/cross_queue_preemption",component:p("/docs/0.10.0/design/cross_queue_preemption","f7a"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/k8shim",component:p("/docs/0.10.0/design/k8shim","f85"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/namespace_resource_quota",component:p("/docs/0.10.0/design/namespace_resource_quota","c44"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/pluggable_app_management",component:p("/docs/0.10.0/design/pluggable_app_management","0cc"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/predicates",component:p("/docs/0.10.0/design/predicates","44d"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/resilience",component:p("/docs/0.10.0/design/resilience","d69"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/scheduler_configuration",component:p("/docs/0.10.0/design/scheduler_configuration","31c"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/scheduler_core_design",component:p("/docs/0.10.0/design/scheduler_core_design","1b4"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/scheduler_object_states",component:p("/docs/0.10.0/design/scheduler_object_states","8b2"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/design/state_aware_scheduling",component:p("/docs/0.10.0/design/state_aware_scheduling","631"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/developer_guide/build",component:p("/docs/0.10.0/developer_guide/build","1df"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/developer_guide/deployment",component:p("/docs/0.10.0/developer_guide/deployment","14a"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/developer_guide/env_setup",component:p("/docs/0.10.0/developer_guide/env_setup","072"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/developer_guide/openshift_development",component:p("/docs/0.10.0/developer_guide/openshift_development","a21"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/get_started/core_features",component:p("/docs/0.10.0/get_started/core_features","964"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.10.0/performance/evaluate_perf_function_with_kubemark","36f"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/performance/metrics",component:p("/docs/0.10.0/performance/metrics","edf"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/performance/profiling",component:p("/docs/0.10.0/performance/profiling","37c"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/acls",component:p("/docs/0.10.0/user_guide/acls","3ff"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/gang_scheduling",component:p("/docs/0.10.0/user_guide/gang_scheduling","433"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/placement_rules",component:p("/docs/0.10.0/user_guide/placement_rules","859"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/queue_config",component:p("/docs/0.10.0/user_guide/queue_config","f93"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/resource_quota_management",component:p("/docs/0.10.0/user_guide/resource_quota_management","49b"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/sorting_policies",component:p("/docs/0.10.0/user_guide/sorting_policies","082"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/trouble_shooting",component:p("/docs/0.10.0/user_guide/trouble_shooting","c2e"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/workloads/run_flink",component:p("/docs/0.10.0/user_guide/workloads/run_flink","968"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/workloads/run_spark",component:p("/docs/0.10.0/user_guide/workloads/run_spark","867"),exact:!0,sidebar:"version-0.10.0/docs"},{path:"/docs/0.10.0/user_guide/workloads/run_tf",component:p("/docs/0.10.0/user_guide/workloads/run_tf","f08"),exact:!0,sidebar:"version-0.10.0/docs"}]},{path:"/docs/0.11.0",component:p("/docs/0.11.0","6ab"),routes:[{path:"/docs/0.11.0/",component:p("/docs/0.11.0/","005"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/api/cluster",component:p("/docs/0.11.0/api/cluster","d64"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/api/scheduler",component:p("/docs/0.11.0/api/scheduler","a28"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/api/system",component:p("/docs/0.11.0/api/system","65a"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/architecture",component:p("/docs/0.11.0/design/architecture","cab"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/cache_removal",component:p("/docs/0.11.0/design/cache_removal","d07"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/cross_queue_preemption",component:p("/docs/0.11.0/design/cross_queue_preemption","66e"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/gang_scheduling",component:p("/docs/0.11.0/design/gang_scheduling","62a"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/k8shim",component:p("/docs/0.11.0/design/k8shim","9a7"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/namespace_resource_quota",component:p("/docs/0.11.0/design/namespace_resource_quota","1fa"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/pluggable_app_management",component:p("/docs/0.11.0/design/pluggable_app_management","479"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/predicates",component:p("/docs/0.11.0/design/predicates","159"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/resilience",component:p("/docs/0.11.0/design/resilience","d96"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/scheduler_configuration",component:p("/docs/0.11.0/design/scheduler_configuration","06e"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/scheduler_core_design",component:p("/docs/0.11.0/design/scheduler_core_design","60f"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/scheduler_object_states",component:p("/docs/0.11.0/design/scheduler_object_states","b79"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/design/state_aware_scheduling",component:p("/docs/0.11.0/design/state_aware_scheduling","7fa"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/developer_guide/build",component:p("/docs/0.11.0/developer_guide/build","cdf"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/developer_guide/deployment",component:p("/docs/0.11.0/developer_guide/deployment","887"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/developer_guide/env_setup",component:p("/docs/0.11.0/developer_guide/env_setup","0f4"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/developer_guide/openshift_development",component:p("/docs/0.11.0/developer_guide/openshift_development","cdc"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/get_started/core_features",component:p("/docs/0.11.0/get_started/core_features","69d"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.11.0/performance/evaluate_perf_function_with_kubemark","a5a"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/performance/metrics",component:p("/docs/0.11.0/performance/metrics","e00"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/performance/profiling",component:p("/docs/0.11.0/performance/profiling","8af"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/acls",component:p("/docs/0.11.0/user_guide/acls","0ed"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/gang_scheduling",component:p("/docs/0.11.0/user_guide/gang_scheduling","059"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/placement_rules",component:p("/docs/0.11.0/user_guide/placement_rules","021"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/queue_config",component:p("/docs/0.11.0/user_guide/queue_config","4c9"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/resource_quota_management",component:p("/docs/0.11.0/user_guide/resource_quota_management","95f"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/sorting_policies",component:p("/docs/0.11.0/user_guide/sorting_policies","766"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/trouble_shooting",component:p("/docs/0.11.0/user_guide/trouble_shooting","084"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/usergroup_resolution",component:p("/docs/0.11.0/user_guide/usergroup_resolution","969"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/workloads/run_flink",component:p("/docs/0.11.0/user_guide/workloads/run_flink","1cf"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/workloads/run_spark",component:p("/docs/0.11.0/user_guide/workloads/run_spark","308"),exact:!0,sidebar:"version-0.11.0/docs"},{path:"/docs/0.11.0/user_guide/workloads/run_tf",component:p("/docs/0.11.0/user_guide/workloads/run_tf","929"),exact:!0,sidebar:"version-0.11.0/docs"}]},{path:"/docs/0.12.1",component:p("/docs/0.12.1","bce"),routes:[{path:"/docs/0.12.1/",component:p("/docs/0.12.1/","f65"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/api/cluster",component:p("/docs/0.12.1/api/cluster","4d5"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/api/scheduler",component:p("/docs/0.12.1/api/scheduler","ebb"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/api/system",component:p("/docs/0.12.1/api/system","e73"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/architecture",component:p("/docs/0.12.1/design/architecture","079"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/cache_removal",component:p("/docs/0.12.1/design/cache_removal","fad"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/cross_queue_preemption",component:p("/docs/0.12.1/design/cross_queue_preemption","ee5"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/gang_scheduling",component:p("/docs/0.12.1/design/gang_scheduling","7e7"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/k8shim",component:p("/docs/0.12.1/design/k8shim","8c3"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/namespace_resource_quota",component:p("/docs/0.12.1/design/namespace_resource_quota","f0b"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/pluggable_app_management",component:p("/docs/0.12.1/design/pluggable_app_management","a24"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/predicates",component:p("/docs/0.12.1/design/predicates","e25"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/resilience",component:p("/docs/0.12.1/design/resilience","a66"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/scheduler_configuration",component:p("/docs/0.12.1/design/scheduler_configuration","52e"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/scheduler_core_design",component:p("/docs/0.12.1/design/scheduler_core_design","3bf"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/scheduler_object_states",component:p("/docs/0.12.1/design/scheduler_object_states","bca"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/design/state_aware_scheduling",component:p("/docs/0.12.1/design/state_aware_scheduling","bf5"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/developer_guide/build",component:p("/docs/0.12.1/developer_guide/build","a78"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/developer_guide/deployment",component:p("/docs/0.12.1/developer_guide/deployment","23f"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/developer_guide/env_setup",component:p("/docs/0.12.1/developer_guide/env_setup","ab1"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/developer_guide/openshift_development",component:p("/docs/0.12.1/developer_guide/openshift_development","5ab"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/get_started/core_features",component:p("/docs/0.12.1/get_started/core_features","275"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.12.1/performance/evaluate_perf_function_with_kubemark","ab1"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/performance/metrics",component:p("/docs/0.12.1/performance/metrics","d9c"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/performance/performance_tutorial",component:p("/docs/0.12.1/performance/performance_tutorial","569"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/performance/profiling",component:p("/docs/0.12.1/performance/profiling","6a7"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/acls",component:p("/docs/0.12.1/user_guide/acls","25f"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/gang_scheduling",component:p("/docs/0.12.1/user_guide/gang_scheduling","311"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/placement_rules",component:p("/docs/0.12.1/user_guide/placement_rules","bd5"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/queue_config",component:p("/docs/0.12.1/user_guide/queue_config","983"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/resource_quota_management",component:p("/docs/0.12.1/user_guide/resource_quota_management","391"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/sorting_policies",component:p("/docs/0.12.1/user_guide/sorting_policies","a75"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/trouble_shooting",component:p("/docs/0.12.1/user_guide/trouble_shooting","fab"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/usergroup_resolution",component:p("/docs/0.12.1/user_guide/usergroup_resolution","2aa"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/workloads/run_flink",component:p("/docs/0.12.1/user_guide/workloads/run_flink","ba3"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/workloads/run_spark",component:p("/docs/0.12.1/user_guide/workloads/run_spark","4f0"),exact:!0,sidebar:"version-0.12.1/docs"},{path:"/docs/0.12.1/user_guide/workloads/run_tf",component:p("/docs/0.12.1/user_guide/workloads/run_tf","407"),exact:!0,sidebar:"version-0.12.1/docs"}]},{path:"/docs/0.12.2",component:p("/docs/0.12.2","01b"),routes:[{path:"/docs/0.12.2/",component:p("/docs/0.12.2/","d7f"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/api/cluster",component:p("/docs/0.12.2/api/cluster","d79"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/api/scheduler",component:p("/docs/0.12.2/api/scheduler","84b"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/api/system",component:p("/docs/0.12.2/api/system","75e"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/architecture",component:p("/docs/0.12.2/design/architecture","fe1"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/cache_removal",component:p("/docs/0.12.2/design/cache_removal","504"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/cross_queue_preemption",component:p("/docs/0.12.2/design/cross_queue_preemption","6f5"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/gang_scheduling",component:p("/docs/0.12.2/design/gang_scheduling","b2e"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/k8shim",component:p("/docs/0.12.2/design/k8shim","63c"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/namespace_resource_quota",component:p("/docs/0.12.2/design/namespace_resource_quota","b4b"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/pluggable_app_management",component:p("/docs/0.12.2/design/pluggable_app_management","5b9"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/predicates",component:p("/docs/0.12.2/design/predicates","1aa"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/resilience",component:p("/docs/0.12.2/design/resilience","b21"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/scheduler_configuration",component:p("/docs/0.12.2/design/scheduler_configuration","3ad"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/scheduler_core_design",component:p("/docs/0.12.2/design/scheduler_core_design","fe7"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/scheduler_object_states",component:p("/docs/0.12.2/design/scheduler_object_states","34e"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/design/state_aware_scheduling",component:p("/docs/0.12.2/design/state_aware_scheduling","24f"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/developer_guide/build",component:p("/docs/0.12.2/developer_guide/build","0d9"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/developer_guide/deployment",component:p("/docs/0.12.2/developer_guide/deployment","d76"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/developer_guide/env_setup",component:p("/docs/0.12.2/developer_guide/env_setup","266"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/developer_guide/openshift_development",component:p("/docs/0.12.2/developer_guide/openshift_development","cbf"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/get_started/core_features",component:p("/docs/0.12.2/get_started/core_features","6a4"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.12.2/performance/evaluate_perf_function_with_kubemark","bdb"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/performance/metrics",component:p("/docs/0.12.2/performance/metrics","7db"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/performance/performance_tutorial",component:p("/docs/0.12.2/performance/performance_tutorial","607"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/performance/profiling",component:p("/docs/0.12.2/performance/profiling","326"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/acls",component:p("/docs/0.12.2/user_guide/acls","b9d"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/gang_scheduling",component:p("/docs/0.12.2/user_guide/gang_scheduling","7e1"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/placement_rules",component:p("/docs/0.12.2/user_guide/placement_rules","e13"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/queue_config",component:p("/docs/0.12.2/user_guide/queue_config","cff"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/resource_quota_management",component:p("/docs/0.12.2/user_guide/resource_quota_management","576"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/sorting_policies",component:p("/docs/0.12.2/user_guide/sorting_policies","17d"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/trouble_shooting",component:p("/docs/0.12.2/user_guide/trouble_shooting","1fb"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/usergroup_resolution",component:p("/docs/0.12.2/user_guide/usergroup_resolution","99c"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/workloads/run_flink",component:p("/docs/0.12.2/user_guide/workloads/run_flink","335"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/workloads/run_spark",component:p("/docs/0.12.2/user_guide/workloads/run_spark","a26"),exact:!0,sidebar:"version-0.12.2/docs"},{path:"/docs/0.12.2/user_guide/workloads/run_tf",component:p("/docs/0.12.2/user_guide/workloads/run_tf","6b7"),exact:!0,sidebar:"version-0.12.2/docs"}]},{path:"/docs/0.8.0",component:p("/docs/0.8.0","c57"),routes:[{path:"/docs/0.8.0/",component:p("/docs/0.8.0/","69c"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/community/coding_guidelines",component:p("/docs/0.8.0/community/coding_guidelines","9ab"),exact:!0,sidebar:"version-0.8.0/community"},{path:"/docs/0.8.0/community/community_sync_up",component:p("/docs/0.8.0/community/community_sync_up","817"),exact:!0,sidebar:"version-0.8.0/community"},{path:"/docs/0.8.0/community/how_to_contribute",component:p("/docs/0.8.0/community/how_to_contribute","5e8"),exact:!0,sidebar:"version-0.8.0/community"},{path:"/docs/0.8.0/community/reporting_issues",component:p("/docs/0.8.0/community/reporting_issues","1ba"),exact:!0,sidebar:"version-0.8.0/community"},{path:"/docs/0.8.0/configuration/acls",component:p("/docs/0.8.0/configuration/acls","774"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/configuration/placement_rules",component:p("/docs/0.8.0/configuration/placement_rules","116"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/configuration/queue_config",component:p("/docs/0.8.0/configuration/queue_config","e58"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/",component:p("/docs/0.8.0/design/","2b8"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/cross_queue_preemption",component:p("/docs/0.8.0/design/cross_queue_preemption","912"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/namespace_resource_quota",component:p("/docs/0.8.0/design/namespace_resource_quota","92a"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/pluggable_app_management",component:p("/docs/0.8.0/design/pluggable_app_management","bd1"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/resilience",component:p("/docs/0.8.0/design/resilience","f01"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/design/scheduler_configuration",component:p("/docs/0.8.0/design/scheduler_configuration","871"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/get_started/developer_guide",component:p("/docs/0.8.0/get_started/developer_guide","bd4"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.8.0/performance/evaluate_perf_function_with_kubemark","59f"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/performance/metrics",component:p("/docs/0.8.0/performance/metrics","208"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/performance/profiling",component:p("/docs/0.8.0/performance/profiling","9b5"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/setup/build_local",component:p("/docs/0.8.0/setup/build_local","937"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/setup/configure_scheduler",component:p("/docs/0.8.0/setup/configure_scheduler","4d2"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/setup/deployment",component:p("/docs/0.8.0/setup/deployment","b96"),exact:!0,sidebar:"version-0.8.0/docs"},{path:"/docs/0.8.0/setup/env_setup",component:p("/docs/0.8.0/setup/env_setup","e2b"),exact:!0,sidebar:"version-0.8.0/docs"}]},{path:"/docs/0.9.0",component:p("/docs/0.9.0","6c7"),routes:[{path:"/docs/0.9.0/",component:p("/docs/0.9.0/","2de"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/api/cluster",component:p("/docs/0.9.0/api/cluster","cdf"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/api/scheduler",component:p("/docs/0.9.0/api/scheduler","cd6"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/api/system",component:p("/docs/0.9.0/api/system","ec1"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/architecture",component:p("/docs/0.9.0/design/architecture","342"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/cross_queue_preemption",component:p("/docs/0.9.0/design/cross_queue_preemption","3e1"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/k8shim",component:p("/docs/0.9.0/design/k8shim","e5f"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/namespace_resource_quota",component:p("/docs/0.9.0/design/namespace_resource_quota","426"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/pluggable_app_management",component:p("/docs/0.9.0/design/pluggable_app_management","cc9"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/predicates",component:p("/docs/0.9.0/design/predicates","d1c"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/resilience",component:p("/docs/0.9.0/design/resilience","d77"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/scheduler_configuration",component:p("/docs/0.9.0/design/scheduler_configuration","f3e"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/scheduler_core_design",component:p("/docs/0.9.0/design/scheduler_core_design","d12"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/scheduler_object_states",component:p("/docs/0.9.0/design/scheduler_object_states","30a"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/design/state_aware_scheduling",component:p("/docs/0.9.0/design/state_aware_scheduling","444"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/developer_guide/build",component:p("/docs/0.9.0/developer_guide/build","365"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/developer_guide/deployment",component:p("/docs/0.9.0/developer_guide/deployment","0bc"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/developer_guide/env_setup",component:p("/docs/0.9.0/developer_guide/env_setup","9a9"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/get_started/core_features",component:p("/docs/0.9.0/get_started/core_features","41a"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/0.9.0/performance/evaluate_perf_function_with_kubemark","daa"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/performance/metrics",component:p("/docs/0.9.0/performance/metrics","b36"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/performance/profiling",component:p("/docs/0.9.0/performance/profiling","8c1"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/acls",component:p("/docs/0.9.0/user_guide/acls","e2a"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/placement_rules",component:p("/docs/0.9.0/user_guide/placement_rules","a03"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/queue_config",component:p("/docs/0.9.0/user_guide/queue_config","f2f"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/resource_quota_management",component:p("/docs/0.9.0/user_guide/resource_quota_management","b2a"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/sorting_policies",component:p("/docs/0.9.0/user_guide/sorting_policies","aab"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/trouble_shooting",component:p("/docs/0.9.0/user_guide/trouble_shooting","51d"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/workloads/run_flink",component:p("/docs/0.9.0/user_guide/workloads/run_flink","789"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/workloads/run_spark",component:p("/docs/0.9.0/user_guide/workloads/run_spark","b38"),exact:!0,sidebar:"version-0.9.0/docs"},{path:"/docs/0.9.0/user_guide/workloads/run_tf",component:p("/docs/0.9.0/user_guide/workloads/run_tf","f79"),exact:!0,sidebar:"version-0.9.0/docs"}]},{path:"/docs/1.0.0",component:p("/docs/1.0.0","f77"),routes:[{path:"/docs/1.0.0/",component:p("/docs/1.0.0/","959"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/api/cluster",component:p("/docs/1.0.0/api/cluster","e16"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/api/scheduler",component:p("/docs/1.0.0/api/scheduler","887"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/api/system",component:p("/docs/1.0.0/api/system","c43"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/architecture",component:p("/docs/1.0.0/design/architecture","f20"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/cache_removal",component:p("/docs/1.0.0/design/cache_removal","d33"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/cross_queue_preemption",component:p("/docs/1.0.0/design/cross_queue_preemption","c5d"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/gang_scheduling",component:p("/docs/1.0.0/design/gang_scheduling","a04"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/interface_message_simplication",component:p("/docs/1.0.0/design/interface_message_simplication","7c3"),exact:!0},{path:"/docs/1.0.0/design/k8shim",component:p("/docs/1.0.0/design/k8shim","2e7"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/namespace_resource_quota",component:p("/docs/1.0.0/design/namespace_resource_quota","7ee"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/pluggable_app_management",component:p("/docs/1.0.0/design/pluggable_app_management","1f9"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/predicates",component:p("/docs/1.0.0/design/predicates","015"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/resilience",component:p("/docs/1.0.0/design/resilience","643"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/scheduler_configuration",component:p("/docs/1.0.0/design/scheduler_configuration","eb7"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/scheduler_core_design",component:p("/docs/1.0.0/design/scheduler_core_design","71e"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/scheduler_object_states",component:p("/docs/1.0.0/design/scheduler_object_states","b52"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/scheduler_plugin",component:p("/docs/1.0.0/design/scheduler_plugin","7c1"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/design/state_aware_scheduling",component:p("/docs/1.0.0/design/state_aware_scheduling","ead"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/developer_guide/build",component:p("/docs/1.0.0/developer_guide/build","e45"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/developer_guide/dependencies",component:p("/docs/1.0.0/developer_guide/dependencies","707"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/developer_guide/deployment",component:p("/docs/1.0.0/developer_guide/deployment","c46"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/developer_guide/env_setup",component:p("/docs/1.0.0/developer_guide/env_setup","9d9"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/developer_guide/openshift_development",component:p("/docs/1.0.0/developer_guide/openshift_development","c40"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/get_started/core_features",component:p("/docs/1.0.0/get_started/core_features","89e"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/1.0.0/performance/evaluate_perf_function_with_kubemark","086"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/performance/metrics",component:p("/docs/1.0.0/performance/metrics","be2"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/performance/performance_tutorial",component:p("/docs/1.0.0/performance/performance_tutorial","342"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/performance/profiling",component:p("/docs/1.0.0/performance/profiling","cd2"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/acls",component:p("/docs/1.0.0/user_guide/acls","1cb"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/deployment_modes",component:p("/docs/1.0.0/user_guide/deployment_modes","b31"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/gang_scheduling",component:p("/docs/1.0.0/user_guide/gang_scheduling","a9a"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/1.0.0/user_guide/labels_and_annotations_in_yunikorn","84b"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/placement_rules",component:p("/docs/1.0.0/user_guide/placement_rules","349"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/queue_config",component:p("/docs/1.0.0/user_guide/queue_config","530"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/resource_quota_management",component:p("/docs/1.0.0/user_guide/resource_quota_management","771"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/sorting_policies",component:p("/docs/1.0.0/user_guide/sorting_policies","1cc"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/trouble_shooting",component:p("/docs/1.0.0/user_guide/trouble_shooting","848"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/usergroup_resolution",component:p("/docs/1.0.0/user_guide/usergroup_resolution","511"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/workloads/run_flink",component:p("/docs/1.0.0/user_guide/workloads/run_flink","5ea"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/workloads/run_spark",component:p("/docs/1.0.0/user_guide/workloads/run_spark","d4a"),exact:!0,sidebar:"docs"},{path:"/docs/1.0.0/user_guide/workloads/run_tf",component:p("/docs/1.0.0/user_guide/workloads/run_tf","b21"),exact:!0,sidebar:"docs"}]},{path:"/docs/1.1.0",component:p("/docs/1.1.0","fd3"),routes:[{path:"/docs/1.1.0/",component:p("/docs/1.1.0/","dd7"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/api/cluster",component:p("/docs/1.1.0/api/cluster","7d7"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/api/scheduler",component:p("/docs/1.1.0/api/scheduler","db3"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/api/system",component:p("/docs/1.1.0/api/system","b82"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/architecture",component:p("/docs/1.1.0/design/architecture","1b8"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/cache_removal",component:p("/docs/1.1.0/design/cache_removal","51e"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/cross_queue_preemption",component:p("/docs/1.1.0/design/cross_queue_preemption","018"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/gang_scheduling",component:p("/docs/1.1.0/design/gang_scheduling","6f0"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/generic_resource",component:p("/docs/1.1.0/design/generic_resource","07c"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/interface_message_simplification",component:p("/docs/1.1.0/design/interface_message_simplification","fd2"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/k8shim",component:p("/docs/1.1.0/design/k8shim","2f3"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/namespace_resource_quota",component:p("/docs/1.1.0/design/namespace_resource_quota","991"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/pluggable_app_management",component:p("/docs/1.1.0/design/pluggable_app_management","056"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/predicates",component:p("/docs/1.1.0/design/predicates","217"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/resilience",component:p("/docs/1.1.0/design/resilience","d7b"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/scheduler_configuration",component:p("/docs/1.1.0/design/scheduler_configuration","3ce"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/scheduler_core_design",component:p("/docs/1.1.0/design/scheduler_core_design","2f5"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/scheduler_object_states",component:p("/docs/1.1.0/design/scheduler_object_states","45c"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/scheduler_plugin",component:p("/docs/1.1.0/design/scheduler_plugin","162"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/simple_preemptor",component:p("/docs/1.1.0/design/simple_preemptor","78c"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/design/state_aware_scheduling",component:p("/docs/1.1.0/design/state_aware_scheduling","23d"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/developer_guide/build",component:p("/docs/1.1.0/developer_guide/build","e25"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/developer_guide/dependencies",component:p("/docs/1.1.0/developer_guide/dependencies","9cc"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/developer_guide/deployment",component:p("/docs/1.1.0/developer_guide/deployment","e9c"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/developer_guide/env_setup",component:p("/docs/1.1.0/developer_guide/env_setup","b47"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/developer_guide/openshift_development",component:p("/docs/1.1.0/developer_guide/openshift_development","350"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/get_started/core_features",component:p("/docs/1.1.0/get_started/core_features","655"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/1.1.0/performance/evaluate_perf_function_with_kubemark","2a4"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/performance/metrics",component:p("/docs/1.1.0/performance/metrics","c77"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/performance/performance_tutorial",component:p("/docs/1.1.0/performance/performance_tutorial","4b5"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/performance/profiling",component:p("/docs/1.1.0/performance/profiling","0e5"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/acls",component:p("/docs/1.1.0/user_guide/acls","2ed"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/deployment_modes",component:p("/docs/1.1.0/user_guide/deployment_modes","c87"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/gang_scheduling",component:p("/docs/1.1.0/user_guide/gang_scheduling","01c"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/1.1.0/user_guide/labels_and_annotations_in_yunikorn","c72"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/placement_rules",component:p("/docs/1.1.0/user_guide/placement_rules","146"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/queue_config",component:p("/docs/1.1.0/user_guide/queue_config","927"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/resource_quota_management",component:p("/docs/1.1.0/user_guide/resource_quota_management","738"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/sorting_policies",component:p("/docs/1.1.0/user_guide/sorting_policies","566"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/trouble_shooting",component:p("/docs/1.1.0/user_guide/trouble_shooting","82b"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/usergroup_resolution",component:p("/docs/1.1.0/user_guide/usergroup_resolution","436"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/workloads/run_flink",component:p("/docs/1.1.0/user_guide/workloads/run_flink","5d1"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/workloads/run_spark",component:p("/docs/1.1.0/user_guide/workloads/run_spark","345"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/workloads/run_tf",component:p("/docs/1.1.0/user_guide/workloads/run_tf","c02"),exact:!0,sidebar:"docs"},{path:"/docs/1.1.0/user_guide/workloads/workload_overview",component:p("/docs/1.1.0/user_guide/workloads/workload_overview","411"),exact:!0,sidebar:"docs"}]},{path:"/docs/1.2.0",component:p("/docs/1.2.0","ee0"),routes:[{path:"/docs/1.2.0/",component:p("/docs/1.2.0/","7f0"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/api/cluster",component:p("/docs/1.2.0/api/cluster","224"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/api/scheduler",component:p("/docs/1.2.0/api/scheduler","180"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/api/system",component:p("/docs/1.2.0/api/system","994"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/archived_design/cross_queue_preemption",component:p("/docs/1.2.0/archived_design/cross_queue_preemption","c1d"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/archived_design/k8shim",component:p("/docs/1.2.0/archived_design/k8shim","f99"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/archived_design/namespace_resource_quota",component:p("/docs/1.2.0/archived_design/namespace_resource_quota","3db"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/archived_design/predicates",component:p("/docs/1.2.0/archived_design/predicates","72d"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/archived_design/scheduler_core_design",component:p("/docs/1.2.0/archived_design/scheduler_core_design","985"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/architecture",component:p("/docs/1.2.0/design/architecture","06b"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/cache_removal",component:p("/docs/1.2.0/design/cache_removal","23a"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/config_v2",component:p("/docs/1.2.0/design/config_v2","f63"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/cross_queue_preemption",component:p("/docs/1.2.0/design/cross_queue_preemption","ce2"),exact:!0},{path:"/docs/1.2.0/design/gang_scheduling",component:p("/docs/1.2.0/design/gang_scheduling","054"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/generic_resource",component:p("/docs/1.2.0/design/generic_resource","e2e"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/interface_message_simplification",component:p("/docs/1.2.0/design/interface_message_simplification","9d7"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/k8shim",component:p("/docs/1.2.0/design/k8shim","a3a"),exact:!0},{path:"/docs/1.2.0/design/namespace_resource_quota",component:p("/docs/1.2.0/design/namespace_resource_quota","2f0"),exact:!0},{path:"/docs/1.2.0/design/pluggable_app_management",component:p("/docs/1.2.0/design/pluggable_app_management","4c4"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/predicates",component:p("/docs/1.2.0/design/predicates","444"),exact:!0},{path:"/docs/1.2.0/design/priority_scheduling",component:p("/docs/1.2.0/design/priority_scheduling","7ef"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/resilience",component:p("/docs/1.2.0/design/resilience","fbc"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/scheduler_configuration",component:p("/docs/1.2.0/design/scheduler_configuration","c96"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/scheduler_core_design",component:p("/docs/1.2.0/design/scheduler_core_design","be0"),exact:!0},{path:"/docs/1.2.0/design/scheduler_object_states",component:p("/docs/1.2.0/design/scheduler_object_states","5e5"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/scheduler_plugin",component:p("/docs/1.2.0/design/scheduler_plugin","7b5"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/simple_preemptor",component:p("/docs/1.2.0/design/simple_preemptor","324"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/state_aware_scheduling",component:p("/docs/1.2.0/design/state_aware_scheduling","5fb"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/user_based_resource_usage_tracking",component:p("/docs/1.2.0/design/user_based_resource_usage_tracking","da7"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/design/user_group",component:p("/docs/1.2.0/design/user_group","0e0"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/developer_guide/build",component:p("/docs/1.2.0/developer_guide/build","216"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/developer_guide/dependencies",component:p("/docs/1.2.0/developer_guide/dependencies","589"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/developer_guide/deployment",component:p("/docs/1.2.0/developer_guide/deployment","d4a"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/developer_guide/env_setup",component:p("/docs/1.2.0/developer_guide/env_setup","a02"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/developer_guide/openshift_development",component:p("/docs/1.2.0/developer_guide/openshift_development","6af"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/get_started/core_features",component:p("/docs/1.2.0/get_started/core_features","0fd"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/1.2.0/performance/evaluate_perf_function_with_kubemark","4e7"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/performance/metrics",component:p("/docs/1.2.0/performance/metrics","ae1"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/performance/performance_tutorial",component:p("/docs/1.2.0/performance/performance_tutorial","dc5"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/performance/profiling",component:p("/docs/1.2.0/performance/profiling","141"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/acls",component:p("/docs/1.2.0/user_guide/acls","620"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/deployment_modes",component:p("/docs/1.2.0/user_guide/deployment_modes","427"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/gang_scheduling",component:p("/docs/1.2.0/user_guide/gang_scheduling","4d8"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/1.2.0/user_guide/labels_and_annotations_in_yunikorn","32b"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/placement_rules",component:p("/docs/1.2.0/user_guide/placement_rules","b54"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/priorities",component:p("/docs/1.2.0/user_guide/priorities","d84"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/queue_config",component:p("/docs/1.2.0/user_guide/queue_config","f05"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/resource_quota_management",component:p("/docs/1.2.0/user_guide/resource_quota_management","b5b"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/service_config",component:p("/docs/1.2.0/user_guide/service_config","e95"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/sorting_policies",component:p("/docs/1.2.0/user_guide/sorting_policies","162"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/troubleshooting",component:p("/docs/1.2.0/user_guide/troubleshooting","102"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/usergroup_resolution",component:p("/docs/1.2.0/user_guide/usergroup_resolution","88e"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/run_flink",component:p("/docs/1.2.0/user_guide/workloads/run_flink","0b3"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/run_mpi",component:p("/docs/1.2.0/user_guide/workloads/run_mpi","c6e"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/run_nvidia",component:p("/docs/1.2.0/user_guide/workloads/run_nvidia","661"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/run_spark",component:p("/docs/1.2.0/user_guide/workloads/run_spark","6bf"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/run_tf",component:p("/docs/1.2.0/user_guide/workloads/run_tf","c01"),exact:!0,sidebar:"docs"},{path:"/docs/1.2.0/user_guide/workloads/workload_overview",component:p("/docs/1.2.0/user_guide/workloads/workload_overview","bac"),exact:!0,sidebar:"docs"}]},{path:"/docs/1.3.0",component:p("/docs/1.3.0","485"),routes:[{path:"/docs/1.3.0/",component:p("/docs/1.3.0/","3c4"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/api/cluster",component:p("/docs/1.3.0/api/cluster","a65"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/api/scheduler",component:p("/docs/1.3.0/api/scheduler","4eb"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/api/system",component:p("/docs/1.3.0/api/system","633"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/archived_design/cross_queue_preemption",component:p("/docs/1.3.0/archived_design/cross_queue_preemption","8e3"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/archived_design/k8shim",component:p("/docs/1.3.0/archived_design/k8shim","e1e"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/archived_design/namespace_resource_quota",component:p("/docs/1.3.0/archived_design/namespace_resource_quota","308"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/archived_design/predicates",component:p("/docs/1.3.0/archived_design/predicates","ced"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/archived_design/scheduler_core_design",component:p("/docs/1.3.0/archived_design/scheduler_core_design","025"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/architecture",component:p("/docs/1.3.0/design/architecture","d07"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/cache_removal",component:p("/docs/1.3.0/design/cache_removal","3a5"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/config_v2",component:p("/docs/1.3.0/design/config_v2","854"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/gang_scheduling",component:p("/docs/1.3.0/design/gang_scheduling","9fe"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/generic_resource",component:p("/docs/1.3.0/design/generic_resource","452"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/interface_message_simplification",component:p("/docs/1.3.0/design/interface_message_simplification","564"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/pluggable_app_management",component:p("/docs/1.3.0/design/pluggable_app_management","bfe"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/preemption",component:p("/docs/1.3.0/design/preemption","7fa"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/priority_scheduling",component:p("/docs/1.3.0/design/priority_scheduling","1b2"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/resilience",component:p("/docs/1.3.0/design/resilience","3e9"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/scheduler_configuration",component:p("/docs/1.3.0/design/scheduler_configuration","b0a"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/scheduler_object_states",component:p("/docs/1.3.0/design/scheduler_object_states","bd5"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/scheduler_plugin",component:p("/docs/1.3.0/design/scheduler_plugin","90b"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/simple_preemptor",component:p("/docs/1.3.0/design/simple_preemptor","205"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/state_aware_scheduling",component:p("/docs/1.3.0/design/state_aware_scheduling","4be"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/user_based_resource_usage_tracking",component:p("/docs/1.3.0/design/user_based_resource_usage_tracking","7ac"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/user_group",component:p("/docs/1.3.0/design/user_group","9b8"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/design/user_group_resource_usage_enforcement",component:p("/docs/1.3.0/design/user_group_resource_usage_enforcement","cec"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/developer_guide/build",component:p("/docs/1.3.0/developer_guide/build","75c"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/developer_guide/dependencies",component:p("/docs/1.3.0/developer_guide/dependencies","c43"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/developer_guide/deployment",component:p("/docs/1.3.0/developer_guide/deployment","2f0"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/developer_guide/env_setup",component:p("/docs/1.3.0/developer_guide/env_setup","c3a"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/developer_guide/openshift_development",component:p("/docs/1.3.0/developer_guide/openshift_development","a4b"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/get_started/core_features",component:p("/docs/1.3.0/get_started/core_features","e43"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/1.3.0/performance/evaluate_perf_function_with_kubemark","ffd"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/performance/metrics",component:p("/docs/1.3.0/performance/metrics","307"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/performance/performance_tutorial",component:p("/docs/1.3.0/performance/performance_tutorial","67f"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/performance/profiling",component:p("/docs/1.3.0/performance/profiling","6ef"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/acls",component:p("/docs/1.3.0/user_guide/acls","360"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/deployment_modes",component:p("/docs/1.3.0/user_guide/deployment_modes","479"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/gang_scheduling",component:p("/docs/1.3.0/user_guide/gang_scheduling","94d"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/1.3.0/user_guide/labels_and_annotations_in_yunikorn","cf3"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/placement_rules",component:p("/docs/1.3.0/user_guide/placement_rules","f26"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/priorities",component:p("/docs/1.3.0/user_guide/priorities","9c5"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/prometheus",component:p("/docs/1.3.0/user_guide/prometheus","b02"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/queue_config",component:p("/docs/1.3.0/user_guide/queue_config","4df"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/resource_quota_management",component:p("/docs/1.3.0/user_guide/resource_quota_management","d9b"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/service_config",component:p("/docs/1.3.0/user_guide/service_config","c07"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/sorting_policies",component:p("/docs/1.3.0/user_guide/sorting_policies","308"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/troubleshooting",component:p("/docs/1.3.0/user_guide/troubleshooting","bbb"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/use_cases",component:p("/docs/1.3.0/user_guide/use_cases","b80"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/usergroup_resolution",component:p("/docs/1.3.0/user_guide/usergroup_resolution","4dd"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/run_flink",component:p("/docs/1.3.0/user_guide/workloads/run_flink","fea"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/run_mpi",component:p("/docs/1.3.0/user_guide/workloads/run_mpi","f21"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/run_nvidia",component:p("/docs/1.3.0/user_guide/workloads/run_nvidia","0f6"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/run_spark",component:p("/docs/1.3.0/user_guide/workloads/run_spark","619"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/run_tf",component:p("/docs/1.3.0/user_guide/workloads/run_tf","eba"),exact:!0,sidebar:"docs"},{path:"/docs/1.3.0/user_guide/workloads/workload_overview",component:p("/docs/1.3.0/user_guide/workloads/workload_overview","c58"),exact:!0,sidebar:"docs"}]},{path:"/docs/1.4.0",component:p("/docs/1.4.0","2b7"),routes:[{path:"/docs/1.4.0/",component:p("/docs/1.4.0/","fbb"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/api/cluster",component:p("/docs/1.4.0/api/cluster","de1"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/api/scheduler",component:p("/docs/1.4.0/api/scheduler","080"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/api/system",component:p("/docs/1.4.0/api/system","214"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/cross_queue_preemption",component:p("/docs/1.4.0/archived_design/cross_queue_preemption","1f9"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/k8shim",component:p("/docs/1.4.0/archived_design/k8shim","2c3"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/namespace_resource_quota",component:p("/docs/1.4.0/archived_design/namespace_resource_quota","bc4"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/pluggable_app_management",component:p("/docs/1.4.0/archived_design/pluggable_app_management","b86"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/predicates",component:p("/docs/1.4.0/archived_design/predicates","32a"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/archived_design/scheduler_core_design",component:p("/docs/1.4.0/archived_design/scheduler_core_design","201"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/architecture",component:p("/docs/1.4.0/design/architecture","a5f"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/cache_removal",component:p("/docs/1.4.0/design/cache_removal","7f7"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/config_v2",component:p("/docs/1.4.0/design/config_v2","c08"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/gang_scheduling",component:p("/docs/1.4.0/design/gang_scheduling","e36"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/generic_resource",component:p("/docs/1.4.0/design/generic_resource","8d7"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/historical_usage_tracking",component:p("/docs/1.4.0/design/historical_usage_tracking","ac9"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/interface_message_simplification",component:p("/docs/1.4.0/design/interface_message_simplification","324"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/preemption",component:p("/docs/1.4.0/design/preemption","022"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/priority_scheduling",component:p("/docs/1.4.0/design/priority_scheduling","b78"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/resilience",component:p("/docs/1.4.0/design/resilience","604"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/scheduler_configuration",component:p("/docs/1.4.0/design/scheduler_configuration","b69"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/scheduler_object_states",component:p("/docs/1.4.0/design/scheduler_object_states","491"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/scheduler_plugin",component:p("/docs/1.4.0/design/scheduler_plugin","678"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/simple_preemptor",component:p("/docs/1.4.0/design/simple_preemptor","208"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/state_aware_scheduling",component:p("/docs/1.4.0/design/state_aware_scheduling","24f"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/user_based_resource_usage_tracking",component:p("/docs/1.4.0/design/user_based_resource_usage_tracking","e96"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/user_group",component:p("/docs/1.4.0/design/user_group","b81"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/design/user_group_resource_usage_enforcement",component:p("/docs/1.4.0/design/user_group_resource_usage_enforcement","306"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/developer_guide/build",component:p("/docs/1.4.0/developer_guide/build","6b3"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/developer_guide/dependencies",component:p("/docs/1.4.0/developer_guide/dependencies","1a6"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/developer_guide/deployment",component:p("/docs/1.4.0/developer_guide/deployment","7d3"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/developer_guide/env_setup",component:p("/docs/1.4.0/developer_guide/env_setup","a70"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/developer_guide/openshift_development",component:p("/docs/1.4.0/developer_guide/openshift_development","fe2"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/get_started/core_features",component:p("/docs/1.4.0/get_started/core_features","b04"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/metrics/queue",component:p("/docs/1.4.0/metrics/queue","9bc"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/metrics/runtime",component:p("/docs/1.4.0/metrics/runtime","b3c"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/metrics/scheduler",component:p("/docs/1.4.0/metrics/scheduler","cea"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/performance/evaluate_perf_function_with_kubemark",component:p("/docs/1.4.0/performance/evaluate_perf_function_with_kubemark","23c"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/performance/metrics",component:p("/docs/1.4.0/performance/metrics","1fd"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/performance/performance_tutorial",component:p("/docs/1.4.0/performance/performance_tutorial","9ca"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/performance/profiling",component:p("/docs/1.4.0/performance/profiling","9f2"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/acls",component:p("/docs/1.4.0/user_guide/acls","179"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/deployment_modes",component:p("/docs/1.4.0/user_guide/deployment_modes","a80"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/gang_scheduling",component:p("/docs/1.4.0/user_guide/gang_scheduling","bc0"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/1.4.0/user_guide/labels_and_annotations_in_yunikorn","49b"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/placement_rules",component:p("/docs/1.4.0/user_guide/placement_rules","6c1"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/preemption_cases",component:p("/docs/1.4.0/user_guide/preemption_cases","c46"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/priorities",component:p("/docs/1.4.0/user_guide/priorities","e2d"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/prometheus",component:p("/docs/1.4.0/user_guide/prometheus","a25"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/queue_config",component:p("/docs/1.4.0/user_guide/queue_config","042"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/resource_quota_management",component:p("/docs/1.4.0/user_guide/resource_quota_management","55d"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/service_config",component:p("/docs/1.4.0/user_guide/service_config","d3a"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/sorting_policies",component:p("/docs/1.4.0/user_guide/sorting_policies","87a"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/troubleshooting",component:p("/docs/1.4.0/user_guide/troubleshooting","576"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/use_cases",component:p("/docs/1.4.0/user_guide/use_cases","ebb"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/usergroup_resolution",component:p("/docs/1.4.0/user_guide/usergroup_resolution","ebc"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/run_flink",component:p("/docs/1.4.0/user_guide/workloads/run_flink","1da"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/run_mpi",component:p("/docs/1.4.0/user_guide/workloads/run_mpi","fb5"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/run_nvidia",component:p("/docs/1.4.0/user_guide/workloads/run_nvidia","515"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/run_spark",component:p("/docs/1.4.0/user_guide/workloads/run_spark","9a3"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/run_tf",component:p("/docs/1.4.0/user_guide/workloads/run_tf","863"),exact:!0,sidebar:"docs"},{path:"/docs/1.4.0/user_guide/workloads/workload_overview",component:p("/docs/1.4.0/user_guide/workloads/workload_overview","3c2"),exact:!0,sidebar:"docs"}]},{path:"/docs/next",component:p("/docs/next","4cd"),routes:[{path:"/docs/next/",component:p("/docs/next/","172"),exact:!0,sidebar:"docs"},{path:"/docs/next/api/cluster",component:p("/docs/next/api/cluster","0c4"),exact:!0,sidebar:"docs"},{path:"/docs/next/api/scheduler",component:p("/docs/next/api/scheduler","139"),exact:!0,sidebar:"docs"},{path:"/docs/next/api/system",component:p("/docs/next/api/system","5f9"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/cross_queue_preemption",component:p("/docs/next/archived_design/cross_queue_preemption","554"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/k8shim",component:p("/docs/next/archived_design/k8shim","56e"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/namespace_resource_quota",component:p("/docs/next/archived_design/namespace_resource_quota","6e7"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/pluggable_app_management",component:p("/docs/next/archived_design/pluggable_app_management","649"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/predicates",component:p("/docs/next/archived_design/predicates","731"),exact:!0,sidebar:"docs"},{path:"/docs/next/archived_design/scheduler_core_design",component:p("/docs/next/archived_design/scheduler_core_design","798"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/architecture",component:p("/docs/next/design/architecture","529"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/cache_removal",component:p("/docs/next/design/cache_removal","6fd"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/config_v2",component:p("/docs/next/design/config_v2","fff"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/gang_scheduling",component:p("/docs/next/design/gang_scheduling","15f"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/generic_resource",component:p("/docs/next/design/generic_resource","8be"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/historical_usage_tracking",component:p("/docs/next/design/historical_usage_tracking","91e"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/interface_message_simplification",component:p("/docs/next/design/interface_message_simplification","31d"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/preemption",component:p("/docs/next/design/preemption","cb0"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/priority_scheduling",component:p("/docs/next/design/priority_scheduling","e5b"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/resilience",component:p("/docs/next/design/resilience","f88"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/scheduler_configuration",component:p("/docs/next/design/scheduler_configuration","f42"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/scheduler_plugin",component:p("/docs/next/design/scheduler_plugin","1a6"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/simple_preemptor",component:p("/docs/next/design/simple_preemptor","f50"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/state_aware_scheduling",component:p("/docs/next/design/state_aware_scheduling","33d"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/user_based_resource_usage_tracking",component:p("/docs/next/design/user_based_resource_usage_tracking","c77"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/user_group",component:p("/docs/next/design/user_group","f09"),exact:!0,sidebar:"docs"},{path:"/docs/next/design/user_group_resource_usage_enforcement",component:p("/docs/next/design/user_group_resource_usage_enforcement","3b5"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/build",component:p("/docs/next/developer_guide/build","072"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/dependencies",component:p("/docs/next/developer_guide/dependencies","51f"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/deployment",component:p("/docs/next/developer_guide/deployment","be3"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/env_setup",component:p("/docs/next/developer_guide/env_setup","c8b"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/openshift_development",component:p("/docs/next/developer_guide/openshift_development","1bb"),exact:!0,sidebar:"docs"},{path:"/docs/next/developer_guide/scheduler_object_states",component:p("/docs/next/developer_guide/scheduler_object_states","a8c"),exact:!0,sidebar:"docs"},{path:"/docs/next/get_started/core_features",component:p("/docs/next/get_started/core_features","8a6"),exact:!0,sidebar:"docs"},{path:"/docs/next/get_started/version",component:p("/docs/next/get_started/version","83c"),exact:!0,sidebar:"docs"},{path:"/docs/next/metrics/queue",component:p("/docs/next/metrics/queue","b0e"),exact:!0,sidebar:"docs"},{path:"/docs/next/metrics/runtime",component:p("/docs/next/metrics/runtime","f63"),exact:!0,sidebar:"docs"},{path:"/docs/next/metrics/scheduler",component:p("/docs/next/metrics/scheduler","f21"),exact:!0,sidebar:"docs"},{path:"/docs/next/performance/evaluate_perf_function_with_kubemark",component:p("/docs/next/performance/evaluate_perf_function_with_kubemark","6d6"),exact:!0,sidebar:"docs"},{path:"/docs/next/performance/evaluate_perf_function_with_kwok",component:p("/docs/next/performance/evaluate_perf_function_with_kwok","ec0"),exact:!0,sidebar:"docs"},{path:"/docs/next/performance/metrics",component:p("/docs/next/performance/metrics","760"),exact:!0,sidebar:"docs"},{path:"/docs/next/performance/performance_tutorial",component:p("/docs/next/performance/performance_tutorial","8c4"),exact:!0,sidebar:"docs"},{path:"/docs/next/performance/profiling",component:p("/docs/next/performance/profiling","0be"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/acls",component:p("/docs/next/user_guide/acls","d8e"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/deployment_modes",component:p("/docs/next/user_guide/deployment_modes","02a"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/gang_scheduling",component:p("/docs/next/user_guide/gang_scheduling","c1e"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/next/user_guide/labels_and_annotations_in_yunikorn","4db"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/placement_rules",component:p("/docs/next/user_guide/placement_rules","557"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/preemption_cases",component:p("/docs/next/user_guide/preemption_cases","726"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/priorities",component:p("/docs/next/user_guide/priorities","eac"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/prometheus",component:p("/docs/next/user_guide/prometheus","6a2"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/queue_config",component:p("/docs/next/user_guide/queue_config","5df"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/resource_quota_management",component:p("/docs/next/user_guide/resource_quota_management","1b6"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/service_config",component:p("/docs/next/user_guide/service_config","76b"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/sorting_policies",component:p("/docs/next/user_guide/sorting_policies","8c7"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/troubleshooting",component:p("/docs/next/user_guide/troubleshooting","727"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/use_cases",component:p("/docs/next/user_guide/use_cases","1ae"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/usergroup_resolution",component:p("/docs/next/user_guide/usergroup_resolution","a3d"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/run_flink",component:p("/docs/next/user_guide/workloads/run_flink","216"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/run_mpi",component:p("/docs/next/user_guide/workloads/run_mpi","f36"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/run_nvidia",component:p("/docs/next/user_guide/workloads/run_nvidia","575"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/run_spark",component:p("/docs/next/user_guide/workloads/run_spark","16e"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/run_tf",component:p("/docs/next/user_guide/workloads/run_tf","189"),exact:!0,sidebar:"docs"},{path:"/docs/next/user_guide/workloads/workload_overview",component:p("/docs/next/user_guide/workloads/workload_overview","df2"),exact:!0,sidebar:"docs"}]},{path:"/docs",component:p("/docs","40d"),routes:[{path:"/docs/",component:p("/docs/","f56"),exact:!0,sidebar:"docs"},{path:"/docs/api/cluster",component:p("/docs/api/cluster","692"),exact:!0,sidebar:"docs"},{path:"/docs/api/scheduler",component:p("/docs/api/scheduler","0c6"),exact:!0,sidebar:"docs"},{path:"/docs/api/system",component:p("/docs/api/system","290"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/cross_queue_preemption",component:p("/docs/archived_design/cross_queue_preemption","65a"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/k8shim",component:p("/docs/archived_design/k8shim","d30"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/namespace_resource_quota",component:p("/docs/archived_design/namespace_resource_quota","526"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/pluggable_app_management",component:p("/docs/archived_design/pluggable_app_management","cba"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/predicates",component:p("/docs/archived_design/predicates","ce9"),exact:!0,sidebar:"docs"},{path:"/docs/archived_design/scheduler_core_design",component:p("/docs/archived_design/scheduler_core_design","83b"),exact:!0,sidebar:"docs"},{path:"/docs/design/architecture",component:p("/docs/design/architecture","542"),exact:!0,sidebar:"docs"},{path:"/docs/design/cache_removal",component:p("/docs/design/cache_removal","c5b"),exact:!0,sidebar:"docs"},{path:"/docs/design/config_v2",component:p("/docs/design/config_v2","203"),exact:!0,sidebar:"docs"},{path:"/docs/design/gang_scheduling",component:p("/docs/design/gang_scheduling","d81"),exact:!0,sidebar:"docs"},{path:"/docs/design/generic_resource",component:p("/docs/design/generic_resource","769"),exact:!0,sidebar:"docs"},{path:"/docs/design/historical_usage_tracking",component:p("/docs/design/historical_usage_tracking","643"),exact:!0,sidebar:"docs"},{path:"/docs/design/interface_message_simplification",component:p("/docs/design/interface_message_simplification","f66"),exact:!0,sidebar:"docs"},{path:"/docs/design/preemption",component:p("/docs/design/preemption","ce6"),exact:!0,sidebar:"docs"},{path:"/docs/design/priority_scheduling",component:p("/docs/design/priority_scheduling","854"),exact:!0,sidebar:"docs"},{path:"/docs/design/resilience",component:p("/docs/design/resilience","f84"),exact:!0,sidebar:"docs"},{path:"/docs/design/scheduler_configuration",component:p("/docs/design/scheduler_configuration","f4d"),exact:!0,sidebar:"docs"},{path:"/docs/design/scheduler_plugin",component:p("/docs/design/scheduler_plugin","e53"),exact:!0,sidebar:"docs"},{path:"/docs/design/simple_preemptor",component:p("/docs/design/simple_preemptor","e41"),exact:!0,sidebar:"docs"},{path:"/docs/design/state_aware_scheduling",component:p("/docs/design/state_aware_scheduling","91a"),exact:!0,sidebar:"docs"},{path:"/docs/design/user_based_resource_usage_tracking",component:p("/docs/design/user_based_resource_usage_tracking","2c1"),exact:!0,sidebar:"docs"},{path:"/docs/design/user_group",component:p("/docs/design/user_group","316"),exact:!0,sidebar:"docs"},{path:"/docs/design/user_group_resource_usage_enforcement",component:p("/docs/design/user_group_resource_usage_enforcement","23e"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/build",component:p("/docs/developer_guide/build","d77"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/dependencies",component:p("/docs/developer_guide/dependencies","46e"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/deployment",component:p("/docs/developer_guide/deployment","62e"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/env_setup",component:p("/docs/developer_guide/env_setup","b36"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/openshift_development",component:p("/docs/developer_guide/openshift_development","ce7"),exact:!0,sidebar:"docs"},{path:"/docs/developer_guide/scheduler_object_states",component:p("/docs/developer_guide/scheduler_object_states","f7a"),exact:!0,sidebar:"docs"},{path:"/docs/get_started/core_features",component:p("/docs/get_started/core_features","ade"),exact:!0,sidebar:"docs"},{path:"/docs/get_started/version",component:p("/docs/get_started/version","da1"),exact:!0,sidebar:"docs"},{path:"/docs/metrics/queue",component:p("/docs/metrics/queue","9bd"),exact:!0,sidebar:"docs"},{path:"/docs/metrics/runtime",component:p("/docs/metrics/runtime","63c"),exact:!0,sidebar:"docs"},{path:"/docs/metrics/scheduler",component:p("/docs/metrics/scheduler","5ea"),exact:!0,sidebar:"docs"},{path:"/docs/performance/evaluate_perf_function_with_kubemark",component:p("/docs/performance/evaluate_perf_function_with_kubemark","2e2"),exact:!0,sidebar:"docs"},{path:"/docs/performance/evaluate_perf_function_with_kwok",component:p("/docs/performance/evaluate_perf_function_with_kwok","e66"),exact:!0,sidebar:"docs"},{path:"/docs/performance/metrics",component:p("/docs/performance/metrics","f49"),exact:!0,sidebar:"docs"},{path:"/docs/performance/performance_tutorial",component:p("/docs/performance/performance_tutorial","213"),exact:!0,sidebar:"docs"},{path:"/docs/performance/profiling",component:p("/docs/performance/profiling","f88"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/acls",component:p("/docs/user_guide/acls","8fd"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/deployment_modes",component:p("/docs/user_guide/deployment_modes","e5a"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/gang_scheduling",component:p("/docs/user_guide/gang_scheduling","ec0"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/labels_and_annotations_in_yunikorn",component:p("/docs/user_guide/labels_and_annotations_in_yunikorn","ba7"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/placement_rules",component:p("/docs/user_guide/placement_rules","894"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/preemption_cases",component:p("/docs/user_guide/preemption_cases","bee"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/priorities",component:p("/docs/user_guide/priorities","432"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/prometheus",component:p("/docs/user_guide/prometheus","083"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/queue_config",component:p("/docs/user_guide/queue_config","367"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/resource_quota_management",component:p("/docs/user_guide/resource_quota_management","dd9"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/service_config",component:p("/docs/user_guide/service_config","2dd"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/sorting_policies",component:p("/docs/user_guide/sorting_policies","2fa"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/troubleshooting",component:p("/docs/user_guide/troubleshooting","d5a"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/use_cases",component:p("/docs/user_guide/use_cases","8fb"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/usergroup_resolution",component:p("/docs/user_guide/usergroup_resolution","808"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/run_flink",component:p("/docs/user_guide/workloads/run_flink","0bb"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/run_mpi",component:p("/docs/user_guide/workloads/run_mpi","c10"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/run_nvidia",component:p("/docs/user_guide/workloads/run_nvidia","556"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/run_spark",component:p("/docs/user_guide/workloads/run_spark","ef5"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/run_tf",component:p("/docs/user_guide/workloads/run_tf","428"),exact:!0,sidebar:"docs"},{path:"/docs/user_guide/workloads/workload_overview",component:p("/docs/user_guide/workloads/workload_overview","162"),exact:!0,sidebar:"docs"}]},{path:"/",component:p("/","cdf"),exact:!0},{path:"*",component:p("*")}]},64640:(e,n,t)=>{"use strict";t.d(n,{o:()=>r,x:()=>s});var o=t(37953);const r=o.createContext(!1);function s(e){let{children:n}=e;const[t,s]=(0,o.useState)(!1);return(0,o.useEffect)((()=>{s(!0)}),[]),o.createElement(r.Provider,{value:t},n)}},64649:(e,n,t)=>{"use strict";var o=t(37953),r=t(88705),s=t(5569),i=t(38478),a=t(59536);const c=[t(64215),t(91430),t(75298),t(63279)];var d=t(47862),u=t(45926),l=t(88562);function p(e){let{children:n}=e;return o.createElement(o.Fragment,null,n)}var g=t(72994),m=t(92549),_=t(77815),f=t(90900),h=t(5615),b=t(92347),v=t(70892),y=t(83876),w=t(49728),k=t(50675);function x(){const{i18n:{defaultLocale:e,localeConfigs:n}}=(0,_.A)(),t=(0,v.o)();return o.createElement(m.A,null,Object.entries(n).map((e=>{let[n,{htmlLang:r}]=e;return o.createElement("link",{key:n,rel:"alternate",href:t.createUrl({locale:n,fullyQualified:!0}),hrefLang:r})})),o.createElement("link",{rel:"alternate",href:t.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function E(e){let{permalink:n}=e;const{siteConfig:{url:t}}=(0,_.A)(),r=function(){const{siteConfig:{url:e}}=(0,_.A)(),{pathname:n}=(0,u.zy)();return e+(0,f.A)(n)}(),s=n?""+t+n:r;return o.createElement(m.A,null,o.createElement("meta",{property:"og:url",content:s}),o.createElement("link",{rel:"canonical",href:s}))}function S(){const{i18n:{currentLocale:e}}=(0,_.A)(),{metadata:n,image:t}=(0,h.p)();return o.createElement(o.Fragment,null,o.createElement(m.A,null,o.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),o.createElement("body",{className:y.w})),t&&o.createElement(b.be,{image:t}),o.createElement(E,null),o.createElement(x,null),o.createElement(k.A,{tag:w.Cy,locale:e}),o.createElement(m.A,null,n.map(((e,n)=>o.createElement("meta",(0,g.A)({key:n},e))))))}const A=new Map;function C(e){if(A.has(e.pathname))return{...e,pathname:A.get(e.pathname)};if((0,l.u)(d.A,e.pathname).some((e=>{let{route:n}=e;return!0===n.exact})))return A.set(e.pathname,e.pathname),e;const n=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return A.set(e.pathname,n),{...e,pathname:n}}var T=t(64640),L=t(90557);function R(e){for(var n=arguments.length,t=new Array(n>1?n-1:0),o=1;o{var o,r;const s=null!=(o=null==(r=n.default)?void 0:r[e])?o:n[e];return null==s?void 0:s(...t)}));return()=>r.forEach((e=>null==e?void 0:e()))}const N=function(e){let{children:n,location:t,previousLocation:r}=e;return(0,o.useLayoutEffect)((()=>{r!==t&&(!function(e){let{location:n,previousLocation:t}=e;if(!t)return;const o=n.pathname===t.pathname,r=n.hash===t.hash,s=n.search===t.search;if(o&&r&&!s)return;const{hash:i}=n;if(i){const e=decodeURIComponent(i.substring(1)),n=document.getElementById(e);null==n||n.scrollIntoView()}else window.scrollTo(0,0)}({location:t,previousLocation:r}),R("onRouteDidUpdate",{previousLocation:r,location:t}))}),[r,t]),n};function P(e){const n=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,l.u)(d.A,e))).flat();return Promise.all(n.map((e=>null==e.route.component.preload?void 0:e.route.component.preload())))}class O extends o.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=a.A.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,n){if(e.location===this.props.location)return n.nextRouteHasLoaded;const t=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:t}),P(t.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:n}=this.props;return o.createElement(N,{previousLocation:this.previousLocation,location:n},o.createElement(u.qh,{location:n,render:()=>e}))}}const I=O,D="__docusaurus-base-url-issue-banner-container",q="__docusaurus-base-url-issue-banner",M="__docusaurus-base-url-issue-banner-suggestion-container",j="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return"\nwindow['"+j+"'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['"+j+"'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('"+D+"');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = "+JSON.stringify(function(e){return'\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n
\n'}(e)).replace(/{window[j]=!1}),[]),o.createElement(o.Fragment,null,!a.A.canUseDOM&&o.createElement(m.A,null,o.createElement("script",null,B(e))),o.createElement("div",{id:D}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:n}}=(0,_.A)(),{pathname:t}=(0,u.zy)();return n&&t===e?o.createElement(F,null):null}function U(){const{siteConfig:{favicon:e,title:n,noIndex:t},i18n:{currentLocale:r,localeConfigs:s}}=(0,_.A)(),i=(0,f.A)(e),{htmlLang:a,direction:c}=s[r];return o.createElement(m.A,null,o.createElement("html",{lang:a,dir:c}),o.createElement("title",null,n),o.createElement("meta",{property:"og:title",content:n}),o.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),t&&o.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&o.createElement("link",{rel:"icon",href:i}))}var $=t(20626);function G(){const e=(0,l.v)(d.A),n=(0,u.zy)();return o.createElement($.A,null,o.createElement(L.l,null,o.createElement(T.x,null,o.createElement(p,null,o.createElement(U,null),o.createElement(S,null),o.createElement(z,null),o.createElement(I,{location:C(n)},e)))))}var H=t(84054);const V=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((n,t)=>{var o,r;if("undefined"==typeof document)return void t();const s=document.createElement("link");s.setAttribute("rel","prefetch"),s.setAttribute("href",e),s.onload=()=>n(),s.onerror=()=>t();const i=null!=(o=document.getElementsByTagName("head")[0])?o:null==(r=document.getElementsByName("script")[0])?void 0:r.parentNode;null==i||i.appendChild(s)}))}:function(e){return new Promise(((n,t)=>{const o=new XMLHttpRequest;o.open("GET",e,!0),o.withCredentials=!0,o.onload=()=>{200===o.status?n():t()},o.send(null)}))};var W=t(44404);const K=new Set,Y=new Set,Q=()=>{var e,n;return(null==(e=navigator.connection)?void 0:e.effectiveType.includes("2g"))||(null==(n=navigator.connection)?void 0:n.saveData)},X={prefetch(e){if(!(e=>!Q()&&!Y.has(e)&&!K.has(e))(e))return!1;K.add(e);const n=(0,l.u)(d.A,e).flatMap((e=>{return n=e.route.path,Object.entries(H).filter((e=>{let[t]=e;return t.replace(/-[^-]+$/,"")===n})).flatMap((e=>{let[,n]=e;return Object.values((0,W.A)(n))}));var n}));return Promise.all(n.map((e=>{const n=t.gca(e);return n&&!n.includes("undefined")?V(n).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!Q()&&!Y.has(e))(e)&&(Y.add(e),P(e))},Z=Object.freeze(X);if(a.A.canUseDOM){window.docusaurus=Z;const e=r.hydrate;P(window.location.pathname).then((()=>{e(o.createElement(i.vd,null,o.createElement(s.Kd,null,o.createElement(G,null))),document.getElementById("__docusaurus"))}))}},90557:(e,n,t)=>{"use strict";t.d(n,{o:()=>u,l:()=>l});var o=t(37953),r=t(4784);const s=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":false,"path":"/docs/next","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/next/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/next/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/next/api/system","sidebar":"docs"},{"id":"archived_design/cross_queue_preemption","path":"/docs/next/archived_design/cross_queue_preemption","sidebar":"docs"},{"id":"archived_design/k8shim","path":"/docs/next/archived_design/k8shim","sidebar":"docs"},{"id":"archived_design/namespace_resource_quota","path":"/docs/next/archived_design/namespace_resource_quota","sidebar":"docs"},{"id":"archived_design/pluggable_app_management","path":"/docs/next/archived_design/pluggable_app_management","sidebar":"docs"},{"id":"archived_design/predicates","path":"/docs/next/archived_design/predicates","sidebar":"docs"},{"id":"archived_design/scheduler_core_design","path":"/docs/next/archived_design/scheduler_core_design","sidebar":"docs"},{"id":"design/architecture","path":"/docs/next/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/next/design/cache_removal","sidebar":"docs"},{"id":"design/config_v2","path":"/docs/next/design/config_v2","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/next/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/next/design/generic_resource","sidebar":"docs"},{"id":"design/historical_usage_tracking","path":"/docs/next/design/historical_usage_tracking","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/next/design/interface_message_simplification","sidebar":"docs"},{"id":"design/preemption","path":"/docs/next/design/preemption","sidebar":"docs"},{"id":"design/priority_scheduling","path":"/docs/next/design/priority_scheduling","sidebar":"docs"},{"id":"design/resilience","path":"/docs/next/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/next/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/next/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/next/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/next/design/state_aware_scheduling","sidebar":"docs"},{"id":"design/user_based_resource_usage_tracking","path":"/docs/next/design/user_based_resource_usage_tracking","sidebar":"docs"},{"id":"design/user_group","path":"/docs/next/design/user_group","sidebar":"docs"},{"id":"design/user_group_resource_usage_enforcement","path":"/docs/next/design/user_group_resource_usage_enforcement","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/next/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/next/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/next/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/next/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/next/developer_guide/openshift_development","sidebar":"docs"},{"id":"developer_guide/scheduler_object_states","path":"/docs/next/developer_guide/scheduler_object_states","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/next/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/next/","sidebar":"docs"},{"id":"get_started/version","path":"/docs/next/get_started/version","sidebar":"docs"},{"id":"metrics/queue","path":"/docs/next/metrics/queue","sidebar":"docs"},{"id":"metrics/runtime","path":"/docs/next/metrics/runtime","sidebar":"docs"},{"id":"metrics/scheduler","path":"/docs/next/metrics/scheduler","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/next/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kwok","path":"/docs/next/performance/evaluate_perf_function_with_kwok","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/next/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/next/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/next/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/next/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/next/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/next/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/next/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/next/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/preemption_cases","path":"/docs/next/user_guide/preemption_cases","sidebar":"docs"},{"id":"user_guide/priorities","path":"/docs/next/user_guide/priorities","sidebar":"docs"},{"id":"user_guide/prometheus","path":"/docs/next/user_guide/prometheus","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/next/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/next/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/service_config","path":"/docs/next/user_guide/service_config","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/next/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/troubleshooting","path":"/docs/next/user_guide/troubleshooting","sidebar":"docs"},{"id":"user_guide/use_cases","path":"/docs/next/user_guide/use_cases","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/next/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/next/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_mpi","path":"/docs/next/user_guide/workloads/run_mpi","sidebar":"docs"},{"id":"user_guide/workloads/run_nvidia","path":"/docs/next/user_guide/workloads/run_nvidia","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/next/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/next/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/next/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/next/","label":"get_started/user_guide"}}}},{"name":"1.5.0","label":"1.5.0","isLast":true,"path":"/docs","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/api/system","sidebar":"docs"},{"id":"archived_design/cross_queue_preemption","path":"/docs/archived_design/cross_queue_preemption","sidebar":"docs"},{"id":"archived_design/k8shim","path":"/docs/archived_design/k8shim","sidebar":"docs"},{"id":"archived_design/namespace_resource_quota","path":"/docs/archived_design/namespace_resource_quota","sidebar":"docs"},{"id":"archived_design/pluggable_app_management","path":"/docs/archived_design/pluggable_app_management","sidebar":"docs"},{"id":"archived_design/predicates","path":"/docs/archived_design/predicates","sidebar":"docs"},{"id":"archived_design/scheduler_core_design","path":"/docs/archived_design/scheduler_core_design","sidebar":"docs"},{"id":"design/architecture","path":"/docs/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/design/cache_removal","sidebar":"docs"},{"id":"design/config_v2","path":"/docs/design/config_v2","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/design/generic_resource","sidebar":"docs"},{"id":"design/historical_usage_tracking","path":"/docs/design/historical_usage_tracking","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/design/interface_message_simplification","sidebar":"docs"},{"id":"design/preemption","path":"/docs/design/preemption","sidebar":"docs"},{"id":"design/priority_scheduling","path":"/docs/design/priority_scheduling","sidebar":"docs"},{"id":"design/resilience","path":"/docs/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/design/state_aware_scheduling","sidebar":"docs"},{"id":"design/user_based_resource_usage_tracking","path":"/docs/design/user_based_resource_usage_tracking","sidebar":"docs"},{"id":"design/user_group","path":"/docs/design/user_group","sidebar":"docs"},{"id":"design/user_group_resource_usage_enforcement","path":"/docs/design/user_group_resource_usage_enforcement","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/developer_guide/openshift_development","sidebar":"docs"},{"id":"developer_guide/scheduler_object_states","path":"/docs/developer_guide/scheduler_object_states","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/","sidebar":"docs"},{"id":"get_started/version","path":"/docs/get_started/version","sidebar":"docs"},{"id":"metrics/queue","path":"/docs/metrics/queue","sidebar":"docs"},{"id":"metrics/runtime","path":"/docs/metrics/runtime","sidebar":"docs"},{"id":"metrics/scheduler","path":"/docs/metrics/scheduler","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kwok","path":"/docs/performance/evaluate_perf_function_with_kwok","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/preemption_cases","path":"/docs/user_guide/preemption_cases","sidebar":"docs"},{"id":"user_guide/priorities","path":"/docs/user_guide/priorities","sidebar":"docs"},{"id":"user_guide/prometheus","path":"/docs/user_guide/prometheus","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/service_config","path":"/docs/user_guide/service_config","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/troubleshooting","path":"/docs/user_guide/troubleshooting","sidebar":"docs"},{"id":"user_guide/use_cases","path":"/docs/user_guide/use_cases","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_mpi","path":"/docs/user_guide/workloads/run_mpi","sidebar":"docs"},{"id":"user_guide/workloads/run_nvidia","path":"/docs/user_guide/workloads/run_nvidia","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/","label":"get_started/user_guide"}}}},{"name":"1.4.0","label":"1.4.0","isLast":false,"path":"/docs/1.4.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/1.4.0/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/1.4.0/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/1.4.0/api/system","sidebar":"docs"},{"id":"archived_design/cross_queue_preemption","path":"/docs/1.4.0/archived_design/cross_queue_preemption","sidebar":"docs"},{"id":"archived_design/k8shim","path":"/docs/1.4.0/archived_design/k8shim","sidebar":"docs"},{"id":"archived_design/namespace_resource_quota","path":"/docs/1.4.0/archived_design/namespace_resource_quota","sidebar":"docs"},{"id":"archived_design/pluggable_app_management","path":"/docs/1.4.0/archived_design/pluggable_app_management","sidebar":"docs"},{"id":"archived_design/predicates","path":"/docs/1.4.0/archived_design/predicates","sidebar":"docs"},{"id":"archived_design/scheduler_core_design","path":"/docs/1.4.0/archived_design/scheduler_core_design","sidebar":"docs"},{"id":"design/architecture","path":"/docs/1.4.0/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/1.4.0/design/cache_removal","sidebar":"docs"},{"id":"design/config_v2","path":"/docs/1.4.0/design/config_v2","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/1.4.0/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/1.4.0/design/generic_resource","sidebar":"docs"},{"id":"design/historical_usage_tracking","path":"/docs/1.4.0/design/historical_usage_tracking","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/1.4.0/design/interface_message_simplification","sidebar":"docs"},{"id":"design/preemption","path":"/docs/1.4.0/design/preemption","sidebar":"docs"},{"id":"design/priority_scheduling","path":"/docs/1.4.0/design/priority_scheduling","sidebar":"docs"},{"id":"design/resilience","path":"/docs/1.4.0/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/1.4.0/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_object_states","path":"/docs/1.4.0/design/scheduler_object_states","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/1.4.0/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/1.4.0/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/1.4.0/design/state_aware_scheduling","sidebar":"docs"},{"id":"design/user_based_resource_usage_tracking","path":"/docs/1.4.0/design/user_based_resource_usage_tracking","sidebar":"docs"},{"id":"design/user_group","path":"/docs/1.4.0/design/user_group","sidebar":"docs"},{"id":"design/user_group_resource_usage_enforcement","path":"/docs/1.4.0/design/user_group_resource_usage_enforcement","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/1.4.0/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/1.4.0/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/1.4.0/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/1.4.0/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/1.4.0/developer_guide/openshift_development","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/1.4.0/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/1.4.0/","sidebar":"docs"},{"id":"metrics/queue","path":"/docs/1.4.0/metrics/queue","sidebar":"docs"},{"id":"metrics/runtime","path":"/docs/1.4.0/metrics/runtime","sidebar":"docs"},{"id":"metrics/scheduler","path":"/docs/1.4.0/metrics/scheduler","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/1.4.0/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/1.4.0/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/1.4.0/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/1.4.0/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/1.4.0/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/1.4.0/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/1.4.0/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/1.4.0/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/1.4.0/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/preemption_cases","path":"/docs/1.4.0/user_guide/preemption_cases","sidebar":"docs"},{"id":"user_guide/priorities","path":"/docs/1.4.0/user_guide/priorities","sidebar":"docs"},{"id":"user_guide/prometheus","path":"/docs/1.4.0/user_guide/prometheus","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/1.4.0/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/1.4.0/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/service_config","path":"/docs/1.4.0/user_guide/service_config","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/1.4.0/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/troubleshooting","path":"/docs/1.4.0/user_guide/troubleshooting","sidebar":"docs"},{"id":"user_guide/use_cases","path":"/docs/1.4.0/user_guide/use_cases","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/1.4.0/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/1.4.0/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_mpi","path":"/docs/1.4.0/user_guide/workloads/run_mpi","sidebar":"docs"},{"id":"user_guide/workloads/run_nvidia","path":"/docs/1.4.0/user_guide/workloads/run_nvidia","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/1.4.0/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/1.4.0/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/1.4.0/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.4.0/","label":"get_started/user_guide"}}}},{"name":"1.3.0","label":"1.3.0","isLast":false,"path":"/docs/1.3.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/1.3.0/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/1.3.0/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/1.3.0/api/system","sidebar":"docs"},{"id":"archived_design/cross_queue_preemption","path":"/docs/1.3.0/archived_design/cross_queue_preemption","sidebar":"docs"},{"id":"archived_design/k8shim","path":"/docs/1.3.0/archived_design/k8shim","sidebar":"docs"},{"id":"archived_design/namespace_resource_quota","path":"/docs/1.3.0/archived_design/namespace_resource_quota","sidebar":"docs"},{"id":"archived_design/predicates","path":"/docs/1.3.0/archived_design/predicates","sidebar":"docs"},{"id":"archived_design/scheduler_core_design","path":"/docs/1.3.0/archived_design/scheduler_core_design","sidebar":"docs"},{"id":"design/architecture","path":"/docs/1.3.0/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/1.3.0/design/cache_removal","sidebar":"docs"},{"id":"design/config_v2","path":"/docs/1.3.0/design/config_v2","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/1.3.0/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/1.3.0/design/generic_resource","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/1.3.0/design/interface_message_simplification","sidebar":"docs"},{"id":"design/pluggable_app_management","path":"/docs/1.3.0/design/pluggable_app_management","sidebar":"docs"},{"id":"design/preemption","path":"/docs/1.3.0/design/preemption","sidebar":"docs"},{"id":"design/priority_scheduling","path":"/docs/1.3.0/design/priority_scheduling","sidebar":"docs"},{"id":"design/resilience","path":"/docs/1.3.0/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/1.3.0/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_object_states","path":"/docs/1.3.0/design/scheduler_object_states","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/1.3.0/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/1.3.0/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/1.3.0/design/state_aware_scheduling","sidebar":"docs"},{"id":"design/user_based_resource_usage_tracking","path":"/docs/1.3.0/design/user_based_resource_usage_tracking","sidebar":"docs"},{"id":"design/user_group","path":"/docs/1.3.0/design/user_group","sidebar":"docs"},{"id":"design/user_group_resource_usage_enforcement","path":"/docs/1.3.0/design/user_group_resource_usage_enforcement","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/1.3.0/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/1.3.0/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/1.3.0/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/1.3.0/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/1.3.0/developer_guide/openshift_development","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/1.3.0/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/1.3.0/","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/1.3.0/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/1.3.0/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/1.3.0/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/1.3.0/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/1.3.0/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/1.3.0/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/1.3.0/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/1.3.0/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/1.3.0/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/priorities","path":"/docs/1.3.0/user_guide/priorities","sidebar":"docs"},{"id":"user_guide/prometheus","path":"/docs/1.3.0/user_guide/prometheus","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/1.3.0/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/1.3.0/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/service_config","path":"/docs/1.3.0/user_guide/service_config","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/1.3.0/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/troubleshooting","path":"/docs/1.3.0/user_guide/troubleshooting","sidebar":"docs"},{"id":"user_guide/use_cases","path":"/docs/1.3.0/user_guide/use_cases","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/1.3.0/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/1.3.0/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_mpi","path":"/docs/1.3.0/user_guide/workloads/run_mpi","sidebar":"docs"},{"id":"user_guide/workloads/run_nvidia","path":"/docs/1.3.0/user_guide/workloads/run_nvidia","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/1.3.0/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/1.3.0/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/1.3.0/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.3.0/","label":"get_started/user_guide"}}}},{"name":"1.2.0","label":"1.2.0","isLast":false,"path":"/docs/1.2.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/1.2.0/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/1.2.0/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/1.2.0/api/system","sidebar":"docs"},{"id":"archived_design/cross_queue_preemption","path":"/docs/1.2.0/archived_design/cross_queue_preemption","sidebar":"docs"},{"id":"archived_design/k8shim","path":"/docs/1.2.0/archived_design/k8shim","sidebar":"docs"},{"id":"archived_design/namespace_resource_quota","path":"/docs/1.2.0/archived_design/namespace_resource_quota","sidebar":"docs"},{"id":"archived_design/predicates","path":"/docs/1.2.0/archived_design/predicates","sidebar":"docs"},{"id":"archived_design/scheduler_core_design","path":"/docs/1.2.0/archived_design/scheduler_core_design","sidebar":"docs"},{"id":"design/architecture","path":"/docs/1.2.0/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/1.2.0/design/cache_removal","sidebar":"docs"},{"id":"design/config_v2","path":"/docs/1.2.0/design/config_v2","sidebar":"docs"},{"id":"design/cross_queue_preemption","path":"/docs/1.2.0/design/cross_queue_preemption"},{"id":"design/gang_scheduling","path":"/docs/1.2.0/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/1.2.0/design/generic_resource","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/1.2.0/design/interface_message_simplification","sidebar":"docs"},{"id":"design/k8shim","path":"/docs/1.2.0/design/k8shim"},{"id":"design/namespace_resource_quota","path":"/docs/1.2.0/design/namespace_resource_quota"},{"id":"design/pluggable_app_management","path":"/docs/1.2.0/design/pluggable_app_management","sidebar":"docs"},{"id":"design/predicates","path":"/docs/1.2.0/design/predicates"},{"id":"design/priority_scheduling","path":"/docs/1.2.0/design/priority_scheduling","sidebar":"docs"},{"id":"design/resilience","path":"/docs/1.2.0/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/1.2.0/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_core_design","path":"/docs/1.2.0/design/scheduler_core_design"},{"id":"design/scheduler_object_states","path":"/docs/1.2.0/design/scheduler_object_states","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/1.2.0/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/1.2.0/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/1.2.0/design/state_aware_scheduling","sidebar":"docs"},{"id":"design/user_based_resource_usage_tracking","path":"/docs/1.2.0/design/user_based_resource_usage_tracking","sidebar":"docs"},{"id":"design/user_group","path":"/docs/1.2.0/design/user_group","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/1.2.0/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/1.2.0/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/1.2.0/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/1.2.0/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/1.2.0/developer_guide/openshift_development","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/1.2.0/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/1.2.0/","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/1.2.0/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/1.2.0/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/1.2.0/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/1.2.0/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/1.2.0/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/1.2.0/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/1.2.0/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/1.2.0/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/1.2.0/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/priorities","path":"/docs/1.2.0/user_guide/priorities","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/1.2.0/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/1.2.0/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/service_config","path":"/docs/1.2.0/user_guide/service_config","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/1.2.0/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/troubleshooting","path":"/docs/1.2.0/user_guide/troubleshooting","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/1.2.0/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/1.2.0/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_mpi","path":"/docs/1.2.0/user_guide/workloads/run_mpi","sidebar":"docs"},{"id":"user_guide/workloads/run_nvidia","path":"/docs/1.2.0/user_guide/workloads/run_nvidia","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/1.2.0/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/1.2.0/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/1.2.0/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.2.0/","label":"get_started/user_guide"}}}},{"name":"1.1.0","label":"1.1.0","isLast":false,"path":"/docs/1.1.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/1.1.0/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/1.1.0/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/1.1.0/api/system","sidebar":"docs"},{"id":"design/architecture","path":"/docs/1.1.0/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/1.1.0/design/cache_removal","sidebar":"docs"},{"id":"design/cross_queue_preemption","path":"/docs/1.1.0/design/cross_queue_preemption","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/1.1.0/design/gang_scheduling","sidebar":"docs"},{"id":"design/generic_resource","path":"/docs/1.1.0/design/generic_resource","sidebar":"docs"},{"id":"design/interface_message_simplification","path":"/docs/1.1.0/design/interface_message_simplification","sidebar":"docs"},{"id":"design/k8shim","path":"/docs/1.1.0/design/k8shim","sidebar":"docs"},{"id":"design/namespace_resource_quota","path":"/docs/1.1.0/design/namespace_resource_quota","sidebar":"docs"},{"id":"design/pluggable_app_management","path":"/docs/1.1.0/design/pluggable_app_management","sidebar":"docs"},{"id":"design/predicates","path":"/docs/1.1.0/design/predicates","sidebar":"docs"},{"id":"design/resilience","path":"/docs/1.1.0/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/1.1.0/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_core_design","path":"/docs/1.1.0/design/scheduler_core_design","sidebar":"docs"},{"id":"design/scheduler_object_states","path":"/docs/1.1.0/design/scheduler_object_states","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/1.1.0/design/scheduler_plugin","sidebar":"docs"},{"id":"design/simple_preemptor","path":"/docs/1.1.0/design/simple_preemptor","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/1.1.0/design/state_aware_scheduling","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/1.1.0/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/1.1.0/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/1.1.0/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/1.1.0/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/1.1.0/developer_guide/openshift_development","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/1.1.0/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/1.1.0/","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/1.1.0/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/1.1.0/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/1.1.0/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/1.1.0/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/1.1.0/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/1.1.0/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/1.1.0/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/1.1.0/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/1.1.0/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/1.1.0/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/1.1.0/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/1.1.0/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/trouble_shooting","path":"/docs/1.1.0/user_guide/trouble_shooting","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/1.1.0/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/1.1.0/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/1.1.0/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/1.1.0/user_guide/workloads/run_tf","sidebar":"docs"},{"id":"user_guide/workloads/workload_overview","path":"/docs/1.1.0/user_guide/workloads/workload_overview","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.1.0/","label":"get_started/user_guide"}}}},{"name":"1.0.0","label":"1.0.0","isLast":false,"path":"/docs/1.0.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/1.0.0/api/cluster","sidebar":"docs"},{"id":"api/scheduler","path":"/docs/1.0.0/api/scheduler","sidebar":"docs"},{"id":"api/system","path":"/docs/1.0.0/api/system","sidebar":"docs"},{"id":"design/architecture","path":"/docs/1.0.0/design/architecture","sidebar":"docs"},{"id":"design/cache_removal","path":"/docs/1.0.0/design/cache_removal","sidebar":"docs"},{"id":"design/cross_queue_preemption","path":"/docs/1.0.0/design/cross_queue_preemption","sidebar":"docs"},{"id":"design/gang_scheduling","path":"/docs/1.0.0/design/gang_scheduling","sidebar":"docs"},{"id":"design/interface_message_simplication","path":"/docs/1.0.0/design/interface_message_simplication"},{"id":"design/k8shim","path":"/docs/1.0.0/design/k8shim","sidebar":"docs"},{"id":"design/namespace_resource_quota","path":"/docs/1.0.0/design/namespace_resource_quota","sidebar":"docs"},{"id":"design/pluggable_app_management","path":"/docs/1.0.0/design/pluggable_app_management","sidebar":"docs"},{"id":"design/predicates","path":"/docs/1.0.0/design/predicates","sidebar":"docs"},{"id":"design/resilience","path":"/docs/1.0.0/design/resilience","sidebar":"docs"},{"id":"design/scheduler_configuration","path":"/docs/1.0.0/design/scheduler_configuration","sidebar":"docs"},{"id":"design/scheduler_core_design","path":"/docs/1.0.0/design/scheduler_core_design","sidebar":"docs"},{"id":"design/scheduler_object_states","path":"/docs/1.0.0/design/scheduler_object_states","sidebar":"docs"},{"id":"design/scheduler_plugin","path":"/docs/1.0.0/design/scheduler_plugin","sidebar":"docs"},{"id":"design/state_aware_scheduling","path":"/docs/1.0.0/design/state_aware_scheduling","sidebar":"docs"},{"id":"developer_guide/build","path":"/docs/1.0.0/developer_guide/build","sidebar":"docs"},{"id":"developer_guide/dependencies","path":"/docs/1.0.0/developer_guide/dependencies","sidebar":"docs"},{"id":"developer_guide/deployment","path":"/docs/1.0.0/developer_guide/deployment","sidebar":"docs"},{"id":"developer_guide/env_setup","path":"/docs/1.0.0/developer_guide/env_setup","sidebar":"docs"},{"id":"developer_guide/openshift_development","path":"/docs/1.0.0/developer_guide/openshift_development","sidebar":"docs"},{"id":"get_started/core_features","path":"/docs/1.0.0/get_started/core_features","sidebar":"docs"},{"id":"get_started/user_guide","path":"/docs/1.0.0/","sidebar":"docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/1.0.0/performance/evaluate_perf_function_with_kubemark","sidebar":"docs"},{"id":"performance/metrics","path":"/docs/1.0.0/performance/metrics","sidebar":"docs"},{"id":"performance/performance_tutorial","path":"/docs/1.0.0/performance/performance_tutorial","sidebar":"docs"},{"id":"performance/profiling","path":"/docs/1.0.0/performance/profiling","sidebar":"docs"},{"id":"user_guide/acls","path":"/docs/1.0.0/user_guide/acls","sidebar":"docs"},{"id":"user_guide/deployment_modes","path":"/docs/1.0.0/user_guide/deployment_modes","sidebar":"docs"},{"id":"user_guide/gang_scheduling","path":"/docs/1.0.0/user_guide/gang_scheduling","sidebar":"docs"},{"id":"user_guide/labels_and_annotations_in_yunikorn","path":"/docs/1.0.0/user_guide/labels_and_annotations_in_yunikorn","sidebar":"docs"},{"id":"user_guide/placement_rules","path":"/docs/1.0.0/user_guide/placement_rules","sidebar":"docs"},{"id":"user_guide/queue_config","path":"/docs/1.0.0/user_guide/queue_config","sidebar":"docs"},{"id":"user_guide/resource_quota_management","path":"/docs/1.0.0/user_guide/resource_quota_management","sidebar":"docs"},{"id":"user_guide/sorting_policies","path":"/docs/1.0.0/user_guide/sorting_policies","sidebar":"docs"},{"id":"user_guide/trouble_shooting","path":"/docs/1.0.0/user_guide/trouble_shooting","sidebar":"docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/1.0.0/user_guide/usergroup_resolution","sidebar":"docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/1.0.0/user_guide/workloads/run_flink","sidebar":"docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/1.0.0/user_guide/workloads/run_spark","sidebar":"docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/1.0.0/user_guide/workloads/run_tf","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/1.0.0/","label":"get_started/user_guide"}}}},{"name":"0.12.2","label":"0.12.2","isLast":false,"path":"/docs/0.12.2","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/0.12.2/api/cluster","sidebar":"version-0.12.2/docs"},{"id":"api/scheduler","path":"/docs/0.12.2/api/scheduler","sidebar":"version-0.12.2/docs"},{"id":"api/system","path":"/docs/0.12.2/api/system","sidebar":"version-0.12.2/docs"},{"id":"design/architecture","path":"/docs/0.12.2/design/architecture","sidebar":"version-0.12.2/docs"},{"id":"design/cache_removal","path":"/docs/0.12.2/design/cache_removal","sidebar":"version-0.12.2/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.12.2/design/cross_queue_preemption","sidebar":"version-0.12.2/docs"},{"id":"design/gang_scheduling","path":"/docs/0.12.2/design/gang_scheduling","sidebar":"version-0.12.2/docs"},{"id":"design/k8shim","path":"/docs/0.12.2/design/k8shim","sidebar":"version-0.12.2/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.12.2/design/namespace_resource_quota","sidebar":"version-0.12.2/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.12.2/design/pluggable_app_management","sidebar":"version-0.12.2/docs"},{"id":"design/predicates","path":"/docs/0.12.2/design/predicates","sidebar":"version-0.12.2/docs"},{"id":"design/resilience","path":"/docs/0.12.2/design/resilience","sidebar":"version-0.12.2/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.12.2/design/scheduler_configuration","sidebar":"version-0.12.2/docs"},{"id":"design/scheduler_core_design","path":"/docs/0.12.2/design/scheduler_core_design","sidebar":"version-0.12.2/docs"},{"id":"design/scheduler_object_states","path":"/docs/0.12.2/design/scheduler_object_states","sidebar":"version-0.12.2/docs"},{"id":"design/state_aware_scheduling","path":"/docs/0.12.2/design/state_aware_scheduling","sidebar":"version-0.12.2/docs"},{"id":"developer_guide/build","path":"/docs/0.12.2/developer_guide/build","sidebar":"version-0.12.2/docs"},{"id":"developer_guide/deployment","path":"/docs/0.12.2/developer_guide/deployment","sidebar":"version-0.12.2/docs"},{"id":"developer_guide/env_setup","path":"/docs/0.12.2/developer_guide/env_setup","sidebar":"version-0.12.2/docs"},{"id":"developer_guide/openshift_development","path":"/docs/0.12.2/developer_guide/openshift_development","sidebar":"version-0.12.2/docs"},{"id":"get_started/core_features","path":"/docs/0.12.2/get_started/core_features","sidebar":"version-0.12.2/docs"},{"id":"get_started/user_guide","path":"/docs/0.12.2/","sidebar":"version-0.12.2/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.12.2/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.12.2/docs"},{"id":"performance/metrics","path":"/docs/0.12.2/performance/metrics","sidebar":"version-0.12.2/docs"},{"id":"performance/performance_tutorial","path":"/docs/0.12.2/performance/performance_tutorial","sidebar":"version-0.12.2/docs"},{"id":"performance/profiling","path":"/docs/0.12.2/performance/profiling","sidebar":"version-0.12.2/docs"},{"id":"user_guide/acls","path":"/docs/0.12.2/user_guide/acls","sidebar":"version-0.12.2/docs"},{"id":"user_guide/gang_scheduling","path":"/docs/0.12.2/user_guide/gang_scheduling","sidebar":"version-0.12.2/docs"},{"id":"user_guide/placement_rules","path":"/docs/0.12.2/user_guide/placement_rules","sidebar":"version-0.12.2/docs"},{"id":"user_guide/queue_config","path":"/docs/0.12.2/user_guide/queue_config","sidebar":"version-0.12.2/docs"},{"id":"user_guide/resource_quota_management","path":"/docs/0.12.2/user_guide/resource_quota_management","sidebar":"version-0.12.2/docs"},{"id":"user_guide/sorting_policies","path":"/docs/0.12.2/user_guide/sorting_policies","sidebar":"version-0.12.2/docs"},{"id":"user_guide/trouble_shooting","path":"/docs/0.12.2/user_guide/trouble_shooting","sidebar":"version-0.12.2/docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/0.12.2/user_guide/usergroup_resolution","sidebar":"version-0.12.2/docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/0.12.2/user_guide/workloads/run_flink","sidebar":"version-0.12.2/docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/0.12.2/user_guide/workloads/run_spark","sidebar":"version-0.12.2/docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/0.12.2/user_guide/workloads/run_tf","sidebar":"version-0.12.2/docs"}],"draftIds":[],"sidebars":{"version-0.12.2/docs":{"link":{"path":"/docs/0.12.2/","label":"version-0.12.2/get_started/user_guide"}}}},{"name":"0.12.1","label":"0.12.1","isLast":false,"path":"/docs/0.12.1","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/0.12.1/api/cluster","sidebar":"version-0.12.1/docs"},{"id":"api/scheduler","path":"/docs/0.12.1/api/scheduler","sidebar":"version-0.12.1/docs"},{"id":"api/system","path":"/docs/0.12.1/api/system","sidebar":"version-0.12.1/docs"},{"id":"design/architecture","path":"/docs/0.12.1/design/architecture","sidebar":"version-0.12.1/docs"},{"id":"design/cache_removal","path":"/docs/0.12.1/design/cache_removal","sidebar":"version-0.12.1/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.12.1/design/cross_queue_preemption","sidebar":"version-0.12.1/docs"},{"id":"design/gang_scheduling","path":"/docs/0.12.1/design/gang_scheduling","sidebar":"version-0.12.1/docs"},{"id":"design/k8shim","path":"/docs/0.12.1/design/k8shim","sidebar":"version-0.12.1/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.12.1/design/namespace_resource_quota","sidebar":"version-0.12.1/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.12.1/design/pluggable_app_management","sidebar":"version-0.12.1/docs"},{"id":"design/predicates","path":"/docs/0.12.1/design/predicates","sidebar":"version-0.12.1/docs"},{"id":"design/resilience","path":"/docs/0.12.1/design/resilience","sidebar":"version-0.12.1/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.12.1/design/scheduler_configuration","sidebar":"version-0.12.1/docs"},{"id":"design/scheduler_core_design","path":"/docs/0.12.1/design/scheduler_core_design","sidebar":"version-0.12.1/docs"},{"id":"design/scheduler_object_states","path":"/docs/0.12.1/design/scheduler_object_states","sidebar":"version-0.12.1/docs"},{"id":"design/state_aware_scheduling","path":"/docs/0.12.1/design/state_aware_scheduling","sidebar":"version-0.12.1/docs"},{"id":"developer_guide/build","path":"/docs/0.12.1/developer_guide/build","sidebar":"version-0.12.1/docs"},{"id":"developer_guide/deployment","path":"/docs/0.12.1/developer_guide/deployment","sidebar":"version-0.12.1/docs"},{"id":"developer_guide/env_setup","path":"/docs/0.12.1/developer_guide/env_setup","sidebar":"version-0.12.1/docs"},{"id":"developer_guide/openshift_development","path":"/docs/0.12.1/developer_guide/openshift_development","sidebar":"version-0.12.1/docs"},{"id":"get_started/core_features","path":"/docs/0.12.1/get_started/core_features","sidebar":"version-0.12.1/docs"},{"id":"get_started/user_guide","path":"/docs/0.12.1/","sidebar":"version-0.12.1/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.12.1/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.12.1/docs"},{"id":"performance/metrics","path":"/docs/0.12.1/performance/metrics","sidebar":"version-0.12.1/docs"},{"id":"performance/performance_tutorial","path":"/docs/0.12.1/performance/performance_tutorial","sidebar":"version-0.12.1/docs"},{"id":"performance/profiling","path":"/docs/0.12.1/performance/profiling","sidebar":"version-0.12.1/docs"},{"id":"user_guide/acls","path":"/docs/0.12.1/user_guide/acls","sidebar":"version-0.12.1/docs"},{"id":"user_guide/gang_scheduling","path":"/docs/0.12.1/user_guide/gang_scheduling","sidebar":"version-0.12.1/docs"},{"id":"user_guide/placement_rules","path":"/docs/0.12.1/user_guide/placement_rules","sidebar":"version-0.12.1/docs"},{"id":"user_guide/queue_config","path":"/docs/0.12.1/user_guide/queue_config","sidebar":"version-0.12.1/docs"},{"id":"user_guide/resource_quota_management","path":"/docs/0.12.1/user_guide/resource_quota_management","sidebar":"version-0.12.1/docs"},{"id":"user_guide/sorting_policies","path":"/docs/0.12.1/user_guide/sorting_policies","sidebar":"version-0.12.1/docs"},{"id":"user_guide/trouble_shooting","path":"/docs/0.12.1/user_guide/trouble_shooting","sidebar":"version-0.12.1/docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/0.12.1/user_guide/usergroup_resolution","sidebar":"version-0.12.1/docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/0.12.1/user_guide/workloads/run_flink","sidebar":"version-0.12.1/docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/0.12.1/user_guide/workloads/run_spark","sidebar":"version-0.12.1/docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/0.12.1/user_guide/workloads/run_tf","sidebar":"version-0.12.1/docs"}],"draftIds":[],"sidebars":{"version-0.12.1/docs":{"link":{"path":"/docs/0.12.1/","label":"version-0.12.1/get_started/user_guide"}}}},{"name":"0.11.0","label":"0.11.0","isLast":false,"path":"/docs/0.11.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/0.11.0/api/cluster","sidebar":"version-0.11.0/docs"},{"id":"api/scheduler","path":"/docs/0.11.0/api/scheduler","sidebar":"version-0.11.0/docs"},{"id":"api/system","path":"/docs/0.11.0/api/system","sidebar":"version-0.11.0/docs"},{"id":"design/architecture","path":"/docs/0.11.0/design/architecture","sidebar":"version-0.11.0/docs"},{"id":"design/cache_removal","path":"/docs/0.11.0/design/cache_removal","sidebar":"version-0.11.0/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.11.0/design/cross_queue_preemption","sidebar":"version-0.11.0/docs"},{"id":"design/gang_scheduling","path":"/docs/0.11.0/design/gang_scheduling","sidebar":"version-0.11.0/docs"},{"id":"design/k8shim","path":"/docs/0.11.0/design/k8shim","sidebar":"version-0.11.0/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.11.0/design/namespace_resource_quota","sidebar":"version-0.11.0/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.11.0/design/pluggable_app_management","sidebar":"version-0.11.0/docs"},{"id":"design/predicates","path":"/docs/0.11.0/design/predicates","sidebar":"version-0.11.0/docs"},{"id":"design/resilience","path":"/docs/0.11.0/design/resilience","sidebar":"version-0.11.0/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.11.0/design/scheduler_configuration","sidebar":"version-0.11.0/docs"},{"id":"design/scheduler_core_design","path":"/docs/0.11.0/design/scheduler_core_design","sidebar":"version-0.11.0/docs"},{"id":"design/scheduler_object_states","path":"/docs/0.11.0/design/scheduler_object_states","sidebar":"version-0.11.0/docs"},{"id":"design/state_aware_scheduling","path":"/docs/0.11.0/design/state_aware_scheduling","sidebar":"version-0.11.0/docs"},{"id":"developer_guide/build","path":"/docs/0.11.0/developer_guide/build","sidebar":"version-0.11.0/docs"},{"id":"developer_guide/deployment","path":"/docs/0.11.0/developer_guide/deployment","sidebar":"version-0.11.0/docs"},{"id":"developer_guide/env_setup","path":"/docs/0.11.0/developer_guide/env_setup","sidebar":"version-0.11.0/docs"},{"id":"developer_guide/openshift_development","path":"/docs/0.11.0/developer_guide/openshift_development","sidebar":"version-0.11.0/docs"},{"id":"get_started/core_features","path":"/docs/0.11.0/get_started/core_features","sidebar":"version-0.11.0/docs"},{"id":"get_started/user_guide","path":"/docs/0.11.0/","sidebar":"version-0.11.0/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.11.0/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.11.0/docs"},{"id":"performance/metrics","path":"/docs/0.11.0/performance/metrics","sidebar":"version-0.11.0/docs"},{"id":"performance/profiling","path":"/docs/0.11.0/performance/profiling","sidebar":"version-0.11.0/docs"},{"id":"user_guide/acls","path":"/docs/0.11.0/user_guide/acls","sidebar":"version-0.11.0/docs"},{"id":"user_guide/gang_scheduling","path":"/docs/0.11.0/user_guide/gang_scheduling","sidebar":"version-0.11.0/docs"},{"id":"user_guide/placement_rules","path":"/docs/0.11.0/user_guide/placement_rules","sidebar":"version-0.11.0/docs"},{"id":"user_guide/queue_config","path":"/docs/0.11.0/user_guide/queue_config","sidebar":"version-0.11.0/docs"},{"id":"user_guide/resource_quota_management","path":"/docs/0.11.0/user_guide/resource_quota_management","sidebar":"version-0.11.0/docs"},{"id":"user_guide/sorting_policies","path":"/docs/0.11.0/user_guide/sorting_policies","sidebar":"version-0.11.0/docs"},{"id":"user_guide/trouble_shooting","path":"/docs/0.11.0/user_guide/trouble_shooting","sidebar":"version-0.11.0/docs"},{"id":"user_guide/usergroup_resolution","path":"/docs/0.11.0/user_guide/usergroup_resolution","sidebar":"version-0.11.0/docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/0.11.0/user_guide/workloads/run_flink","sidebar":"version-0.11.0/docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/0.11.0/user_guide/workloads/run_spark","sidebar":"version-0.11.0/docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/0.11.0/user_guide/workloads/run_tf","sidebar":"version-0.11.0/docs"}],"draftIds":[],"sidebars":{"version-0.11.0/docs":{"link":{"path":"/docs/0.11.0/","label":"version-0.11.0/get_started/user_guide"}}}},{"name":"0.10.0","label":"0.10.0","isLast":false,"path":"/docs/0.10.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/0.10.0/api/cluster","sidebar":"version-0.10.0/docs"},{"id":"api/scheduler","path":"/docs/0.10.0/api/scheduler","sidebar":"version-0.10.0/docs"},{"id":"api/system","path":"/docs/0.10.0/api/system","sidebar":"version-0.10.0/docs"},{"id":"design/architecture","path":"/docs/0.10.0/design/architecture","sidebar":"version-0.10.0/docs"},{"id":"design/cache_removal","path":"/docs/0.10.0/design/cache_removal","sidebar":"version-0.10.0/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.10.0/design/cross_queue_preemption","sidebar":"version-0.10.0/docs"},{"id":"design/k8shim","path":"/docs/0.10.0/design/k8shim","sidebar":"version-0.10.0/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.10.0/design/namespace_resource_quota","sidebar":"version-0.10.0/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.10.0/design/pluggable_app_management","sidebar":"version-0.10.0/docs"},{"id":"design/predicates","path":"/docs/0.10.0/design/predicates","sidebar":"version-0.10.0/docs"},{"id":"design/resilience","path":"/docs/0.10.0/design/resilience","sidebar":"version-0.10.0/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.10.0/design/scheduler_configuration","sidebar":"version-0.10.0/docs"},{"id":"design/scheduler_core_design","path":"/docs/0.10.0/design/scheduler_core_design","sidebar":"version-0.10.0/docs"},{"id":"design/scheduler_object_states","path":"/docs/0.10.0/design/scheduler_object_states","sidebar":"version-0.10.0/docs"},{"id":"design/state_aware_scheduling","path":"/docs/0.10.0/design/state_aware_scheduling","sidebar":"version-0.10.0/docs"},{"id":"developer_guide/build","path":"/docs/0.10.0/developer_guide/build","sidebar":"version-0.10.0/docs"},{"id":"developer_guide/deployment","path":"/docs/0.10.0/developer_guide/deployment","sidebar":"version-0.10.0/docs"},{"id":"developer_guide/env_setup","path":"/docs/0.10.0/developer_guide/env_setup","sidebar":"version-0.10.0/docs"},{"id":"developer_guide/openshift_development","path":"/docs/0.10.0/developer_guide/openshift_development","sidebar":"version-0.10.0/docs"},{"id":"get_started/core_features","path":"/docs/0.10.0/get_started/core_features","sidebar":"version-0.10.0/docs"},{"id":"get_started/user_guide","path":"/docs/0.10.0/","sidebar":"version-0.10.0/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.10.0/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.10.0/docs"},{"id":"performance/metrics","path":"/docs/0.10.0/performance/metrics","sidebar":"version-0.10.0/docs"},{"id":"performance/profiling","path":"/docs/0.10.0/performance/profiling","sidebar":"version-0.10.0/docs"},{"id":"user_guide/acls","path":"/docs/0.10.0/user_guide/acls","sidebar":"version-0.10.0/docs"},{"id":"user_guide/gang_scheduling","path":"/docs/0.10.0/user_guide/gang_scheduling","sidebar":"version-0.10.0/docs"},{"id":"user_guide/placement_rules","path":"/docs/0.10.0/user_guide/placement_rules","sidebar":"version-0.10.0/docs"},{"id":"user_guide/queue_config","path":"/docs/0.10.0/user_guide/queue_config","sidebar":"version-0.10.0/docs"},{"id":"user_guide/resource_quota_management","path":"/docs/0.10.0/user_guide/resource_quota_management","sidebar":"version-0.10.0/docs"},{"id":"user_guide/sorting_policies","path":"/docs/0.10.0/user_guide/sorting_policies","sidebar":"version-0.10.0/docs"},{"id":"user_guide/trouble_shooting","path":"/docs/0.10.0/user_guide/trouble_shooting","sidebar":"version-0.10.0/docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/0.10.0/user_guide/workloads/run_flink","sidebar":"version-0.10.0/docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/0.10.0/user_guide/workloads/run_spark","sidebar":"version-0.10.0/docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/0.10.0/user_guide/workloads/run_tf","sidebar":"version-0.10.0/docs"}],"draftIds":[],"sidebars":{"version-0.10.0/docs":{"link":{"path":"/docs/0.10.0/","label":"version-0.10.0/get_started/user_guide"}}}},{"name":"0.9.0","label":"0.9.0","isLast":false,"path":"/docs/0.9.0","mainDocId":"get_started/user_guide","docs":[{"id":"api/cluster","path":"/docs/0.9.0/api/cluster","sidebar":"version-0.9.0/docs"},{"id":"api/scheduler","path":"/docs/0.9.0/api/scheduler","sidebar":"version-0.9.0/docs"},{"id":"api/system","path":"/docs/0.9.0/api/system","sidebar":"version-0.9.0/docs"},{"id":"design/architecture","path":"/docs/0.9.0/design/architecture","sidebar":"version-0.9.0/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.9.0/design/cross_queue_preemption","sidebar":"version-0.9.0/docs"},{"id":"design/k8shim","path":"/docs/0.9.0/design/k8shim","sidebar":"version-0.9.0/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.9.0/design/namespace_resource_quota","sidebar":"version-0.9.0/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.9.0/design/pluggable_app_management","sidebar":"version-0.9.0/docs"},{"id":"design/predicates","path":"/docs/0.9.0/design/predicates","sidebar":"version-0.9.0/docs"},{"id":"design/resilience","path":"/docs/0.9.0/design/resilience","sidebar":"version-0.9.0/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.9.0/design/scheduler_configuration","sidebar":"version-0.9.0/docs"},{"id":"design/scheduler_core_design","path":"/docs/0.9.0/design/scheduler_core_design","sidebar":"version-0.9.0/docs"},{"id":"design/scheduler_object_states","path":"/docs/0.9.0/design/scheduler_object_states","sidebar":"version-0.9.0/docs"},{"id":"design/state_aware_scheduling","path":"/docs/0.9.0/design/state_aware_scheduling","sidebar":"version-0.9.0/docs"},{"id":"developer_guide/build","path":"/docs/0.9.0/developer_guide/build","sidebar":"version-0.9.0/docs"},{"id":"developer_guide/deployment","path":"/docs/0.9.0/developer_guide/deployment","sidebar":"version-0.9.0/docs"},{"id":"developer_guide/env_setup","path":"/docs/0.9.0/developer_guide/env_setup","sidebar":"version-0.9.0/docs"},{"id":"get_started/core_features","path":"/docs/0.9.0/get_started/core_features","sidebar":"version-0.9.0/docs"},{"id":"get_started/user_guide","path":"/docs/0.9.0/","sidebar":"version-0.9.0/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.9.0/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.9.0/docs"},{"id":"performance/metrics","path":"/docs/0.9.0/performance/metrics","sidebar":"version-0.9.0/docs"},{"id":"performance/profiling","path":"/docs/0.9.0/performance/profiling","sidebar":"version-0.9.0/docs"},{"id":"user_guide/acls","path":"/docs/0.9.0/user_guide/acls","sidebar":"version-0.9.0/docs"},{"id":"user_guide/placement_rules","path":"/docs/0.9.0/user_guide/placement_rules","sidebar":"version-0.9.0/docs"},{"id":"user_guide/queue_config","path":"/docs/0.9.0/user_guide/queue_config","sidebar":"version-0.9.0/docs"},{"id":"user_guide/resource_quota_management","path":"/docs/0.9.0/user_guide/resource_quota_management","sidebar":"version-0.9.0/docs"},{"id":"user_guide/sorting_policies","path":"/docs/0.9.0/user_guide/sorting_policies","sidebar":"version-0.9.0/docs"},{"id":"user_guide/trouble_shooting","path":"/docs/0.9.0/user_guide/trouble_shooting","sidebar":"version-0.9.0/docs"},{"id":"user_guide/workloads/run_flink","path":"/docs/0.9.0/user_guide/workloads/run_flink","sidebar":"version-0.9.0/docs"},{"id":"user_guide/workloads/run_spark","path":"/docs/0.9.0/user_guide/workloads/run_spark","sidebar":"version-0.9.0/docs"},{"id":"user_guide/workloads/run_tf","path":"/docs/0.9.0/user_guide/workloads/run_tf","sidebar":"version-0.9.0/docs"}],"draftIds":[],"sidebars":{"version-0.9.0/docs":{"link":{"path":"/docs/0.9.0/","label":"version-0.9.0/get_started/user_guide"}}}},{"name":"0.8.0","label":"0.8.0","isLast":false,"path":"/docs/0.8.0","mainDocId":"get_started/user_guide","docs":[{"id":"community/coding_guidelines","path":"/docs/0.8.0/community/coding_guidelines","sidebar":"version-0.8.0/community"},{"id":"community/community_sync_up","path":"/docs/0.8.0/community/community_sync_up","sidebar":"version-0.8.0/community"},{"id":"community/how_to_contribute","path":"/docs/0.8.0/community/how_to_contribute","sidebar":"version-0.8.0/community"},{"id":"community/reporting_issues","path":"/docs/0.8.0/community/reporting_issues","sidebar":"version-0.8.0/community"},{"id":"configuration/acls","path":"/docs/0.8.0/configuration/acls","sidebar":"version-0.8.0/docs"},{"id":"configuration/placement_rules","path":"/docs/0.8.0/configuration/placement_rules","sidebar":"version-0.8.0/docs"},{"id":"configuration/queue_config","path":"/docs/0.8.0/configuration/queue_config","sidebar":"version-0.8.0/docs"},{"id":"design/cross_queue_preemption","path":"/docs/0.8.0/design/cross_queue_preemption","sidebar":"version-0.8.0/docs"},{"id":"design/design","path":"/docs/0.8.0/design/","sidebar":"version-0.8.0/docs"},{"id":"design/namespace_resource_quota","path":"/docs/0.8.0/design/namespace_resource_quota","sidebar":"version-0.8.0/docs"},{"id":"design/pluggable_app_management","path":"/docs/0.8.0/design/pluggable_app_management","sidebar":"version-0.8.0/docs"},{"id":"design/resilience","path":"/docs/0.8.0/design/resilience","sidebar":"version-0.8.0/docs"},{"id":"design/scheduler_configuration","path":"/docs/0.8.0/design/scheduler_configuration","sidebar":"version-0.8.0/docs"},{"id":"get_started/developer_guide","path":"/docs/0.8.0/get_started/developer_guide","sidebar":"version-0.8.0/docs"},{"id":"get_started/user_guide","path":"/docs/0.8.0/","sidebar":"version-0.8.0/docs"},{"id":"performance/evaluate_perf_function_with_kubemark","path":"/docs/0.8.0/performance/evaluate_perf_function_with_kubemark","sidebar":"version-0.8.0/docs"},{"id":"performance/metrics","path":"/docs/0.8.0/performance/metrics","sidebar":"version-0.8.0/docs"},{"id":"performance/profiling","path":"/docs/0.8.0/performance/profiling","sidebar":"version-0.8.0/docs"},{"id":"setup/build_local","path":"/docs/0.8.0/setup/build_local","sidebar":"version-0.8.0/docs"},{"id":"setup/configure_scheduler","path":"/docs/0.8.0/setup/configure_scheduler","sidebar":"version-0.8.0/docs"},{"id":"setup/deployment","path":"/docs/0.8.0/setup/deployment","sidebar":"version-0.8.0/docs"},{"id":"setup/env_setup","path":"/docs/0.8.0/setup/env_setup","sidebar":"version-0.8.0/docs"}],"draftIds":[],"sidebars":{"version-0.8.0/docs":{"link":{"path":"/docs/0.8.0/","label":"version-0.8.0/get_started/user_guide"}},"version-0.8.0/community":{"link":{"path":"/docs/0.8.0/community/how_to_contribute","label":"version-0.8.0/community/how_to_contribute"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var a=t(22654);const c=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"2.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.1"}}}'),d={siteConfig:r.default,siteMetadata:c,globalData:s,i18n:i,codeTranslations:a},u=o.createContext(d);function l(e){let{children:n}=e;return o.createElement(u.Provider,{value:d},n)}},20626:(e,n,t)=>{"use strict";t.d(n,{A:()=>p});var o=t(37953),r=t(59536),s=t(92549),i=t(16097),a=t(37129);function c(e){let{error:n,tryAgain:t}=e;return o.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},o.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),o.createElement("button",{type:"button",onClick:t,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),o.createElement(d,{error:n}))}function d(e){let{error:n}=e;const t=(0,i.getErrorCausalChain)(n).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{style:{whiteSpace:"pre-wrap"}},t)}function u(e){let{error:n,tryAgain:t}=e;return o.createElement(p,{fallback:()=>o.createElement(c,{error:n,tryAgain:t})},o.createElement(s.A,null,o.createElement("title",null,"Page Error")),o.createElement(a.A,null,o.createElement(c,{error:n,tryAgain:t})))}const l=e=>o.createElement(u,e);class p extends o.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){r.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:n}=this.state;if(n){var t;const e={error:n,tryAgain:()=>this.setState({error:null})};return(null!=(t=this.props.fallback)?t:l)(e)}return null!=e?e:null}}},59536:(e,n,t)=>{"use strict";t.d(n,{A:()=>r});const o="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,r={canUseDOM:o,canUseEventListeners:o&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:o&&"IntersectionObserver"in window,canUseViewport:o&&"screen"in window}},92549:(e,n,t)=>{"use strict";t.d(n,{A:()=>s});var o=t(37953),r=t(38478);function s(e){return o.createElement(r.mg,e)}},75040:(e,n,t)=>{"use strict";t.d(n,{A:()=>g});var o=t(72994),r=t(37953),s=t(5569),i=t(16097),a=t(77815),c=t(53021),d=t(59536);const u=r.createContext({collectLink:()=>{}});var l=t(90900);function p(e,n){var t,p;let{isNavLink:g,to:m,href:_,activeClassName:f,isActive:h,"data-noBrokenLinkCheck":b,autoAddBaseUrl:v=!0,...y}=e;const{siteConfig:{trailingSlash:w,baseUrl:k}}=(0,a.A)(),{withBaseUrl:x}=(0,l.h)(),E=(0,r.useContext)(u),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(n,(()=>S.current));const A=m||_;const C=(0,c.A)(A),T=null==A?void 0:A.replace("pathname://","");let L=void 0!==T?(R=T,v&&(e=>e.startsWith("/"))(R)?x(R):R):void 0;var R;L&&C&&(L=(0,i.applyTrailingSlash)(L,{trailingSlash:w,baseUrl:k}));const N=(0,r.useRef)(!1),P=g?s.k2:s.N_,O=d.A.canUseIntersectionObserver,I=(0,r.useRef)(),D=()=>{N.current||null==L||(window.docusaurus.preload(L),N.current=!0)};(0,r.useEffect)((()=>(!O&&C&&null!=L&&window.docusaurus.prefetch(L),()=>{O&&I.current&&I.current.disconnect()})),[I,L,O,C]);const q=null!=(t=null==(p=L)?void 0:p.startsWith("#"))&&t,M=!L||!C||q;return M||b||E.collectLink(L),M?r.createElement("a",(0,o.A)({ref:S,href:L},A&&!C&&{target:"_blank",rel:"noopener noreferrer"},y)):r.createElement(P,(0,o.A)({},y,{onMouseEnter:D,onTouchStart:D,innerRef:e=>{S.current=e,O&&e&&C&&(I.current=new window.IntersectionObserver((n=>{n.forEach((n=>{e===n.target&&(n.isIntersecting||n.intersectionRatio>0)&&(I.current.unobserve(e),I.current.disconnect(),null!=L&&window.docusaurus.prefetch(L))}))})),I.current.observe(e))},to:L},g&&{isActive:h,activeClassName:f}))}const g=r.forwardRef(p)},81809:(e,n,t)=>{"use strict";t.d(n,{A:()=>c,T:()=>a});var o=t(37953);function r(e,n){const t=e.split(/(\{\w+\})/).map(((e,t)=>{if(t%2==1){const t=null==n?void 0:n[e.slice(1,-1)];if(void 0!==t)return t}return e}));return t.some((e=>(0,o.isValidElement)(e)))?t.map(((e,n)=>(0,o.isValidElement)(e)?o.cloneElement(e,{key:n}):e)).filter((e=>""!==e)):t.join("")}var s=t(22654);function i(e){var n,t;let{id:o,message:r}=e;if(void 0===o&&void 0===r)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!=(n=null!=(t=s[null!=o?o:r])?t:r)?n:o}function a(e,n){let{message:t,id:o}=e;return r(i({message:t,id:o}),n)}function c(e){let{children:n,id:t,values:s}=e;if(n&&"string"!=typeof n)throw console.warn("Illegal children",n),new Error("The Docusaurus component only accept simple string values");const a=i({message:n,id:t});return o.createElement(o.Fragment,null,r(a,s))}},28230:(e,n,t)=>{"use strict";t.d(n,{W:()=>o});const o="default"},53021:(e,n,t)=>{"use strict";function o(e){return/^(?:\w*:|\/\/)/.test(e)}function r(e){return void 0!==e&&!o(e)}t.d(n,{A:()=>r,z:()=>o})},90900:(e,n,t)=>{"use strict";t.d(n,{A:()=>a,h:()=>i});var o=t(37953),r=t(77815),s=t(53021);function i(){const{siteConfig:{baseUrl:e,url:n}}=(0,r.A)(),t=(0,o.useCallback)(((t,o)=>function(e,n,t,o){let{forcePrependBaseUrl:r=!1,absolute:i=!1}=void 0===o?{}:o;if(!t||t.startsWith("#")||(0,s.z)(t))return t;if(r)return n+t.replace(/^\//,"");if(t===n.replace(/\/$/,""))return n;const a=t.startsWith(n)?t:n+t.replace(/^\//,"");return i?e+a:a}(n,e,t,o)),[n,e]);return{withBaseUrl:t}}function a(e,n){void 0===n&&(n={});const{withBaseUrl:t}=i();return t(e,n)}},77815:(e,n,t)=>{"use strict";t.d(n,{A:()=>s});var o=t(37953),r=t(90557);function s(){return(0,o.useContext)(r.o)}},82182:(e,n,t)=>{"use strict";t.d(n,{A:()=>s});var o=t(37953),r=t(64640);function s(){return(0,o.useContext)(r.o)}},44404:(e,n,t)=>{"use strict";t.d(n,{A:()=>r});const o=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function r(e){const n={};return function e(t,r){Object.entries(t).forEach((t=>{let[s,i]=t;const a=r?r+"."+s:s;o(i)?e(i,a):n[a]=i}))}(e),n}},86131:(e,n,t)=>{"use strict";t.d(n,{W:()=>s,o:()=>r});var o=t(37953);const r=o.createContext(null);function s(e){let{children:n,value:t}=e;const s=o.useContext(r),i=(0,o.useMemo)((()=>function(e){let{parent:n,value:t}=e;if(!n){if(!t)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in t))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return t}const o={...n.data,...null==t?void 0:t.data};return{plugin:n.plugin,data:o}}({parent:s,value:t})),[s,t]);return o.createElement(r.Provider,{value:i},n)}},82952:(e,n,t)=>{"use strict";t.d(n,{zK:()=>h,vT:()=>g,gk:()=>m,Gy:()=>l,HW:()=>b,ht:()=>p,r7:()=>f,jh:()=>_});var o=t(45926),r=t(77815),s=t(28230);function i(e,n){void 0===n&&(n={});const t=function(){const{globalData:e}=(0,r.A)();return e}()[e];if(!t&&n.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return t}const a=e=>e.versions.find((e=>e.isLast));function c(e,n){const t=a(e);return[...e.versions.filter((e=>e!==t)),t].find((e=>!!(0,o.B6)(n,{path:e.path,exact:!1,strict:!1})))}function d(e,n){const t=c(e,n),r=null==t?void 0:t.docs.find((e=>!!(0,o.B6)(n,{path:e.path,exact:!0,strict:!1})));return{activeVersion:t,activeDoc:r,alternateDocVersions:r?function(n){const t={};return e.versions.forEach((e=>{e.docs.forEach((o=>{o.id===n&&(t[e.name]=o)}))})),t}(r.id):{}}}const u={},l=()=>{var e;return null!=(e=i("docusaurus-plugin-content-docs"))?e:u},p=e=>function(e,n,t){void 0===n&&(n=s.W),void 0===t&&(t={});const o=i(e),r=null==o?void 0:o[n];if(!r&&t.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+n+'".');return r}("docusaurus-plugin-content-docs",e,{failfast:!0});function g(e){void 0===e&&(e={});const n=l(),{pathname:t}=(0,o.zy)();return function(e,n,t){void 0===t&&(t={});const r=Object.entries(e).sort(((e,n)=>n[1].path.localeCompare(e[1].path))).find((e=>{let[,t]=e;return!!(0,o.B6)(n,{path:t.path,exact:!1,strict:!1})})),s=r?{pluginId:r[0],pluginData:r[1]}:void 0;if(!s&&t.failfast)throw new Error("Can't find active docs plugin for \""+n+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((e=>e.path)).join(", "));return s}(n,t,e)}function m(e){void 0===e&&(e={});const n=g(e),{pathname:t}=(0,o.zy)();if(!n)return;return{activePlugin:n,activeVersion:c(n.pluginData,t)}}function _(e){return p(e).versions}function f(e){const n=p(e);return a(n)}function h(e){const n=p(e),{pathname:t}=(0,o.zy)();return d(n,t)}function b(e){const n=p(e),{pathname:t}=(0,o.zy)();return function(e,n){const t=a(e);return{latestDocSuggestion:d(e,n).alternateDocVersions[t.name],latestVersionSuggestion:t}}(n,t)}},67020:(e,n,t)=>{"use strict";function o(e,n){e.prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n}function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function s(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(){return i=Object.assign||function(e){for(var n=1;n{"use strict";t.r(n),t.d(n,{default:()=>s});var o=t(58744),r=t.n(o);r().configure({showSpinner:!1});const s={onRouteUpdate(e){let{location:n,previousLocation:t}=e;if(t&&n.pathname!==t.pathname){const e=window.setTimeout((()=>{r().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){r().done()}}},91430:(e,n,t)=>{"use strict";t.r(n);var o=t(97942),r=t(4784);!function(e){const{themeConfig:{prism:n}}=r.default,{additionalLanguages:o}=n;globalThis.Prism=e,o.forEach((e=>{t(32859)("./prism-"+e)})),delete globalThis.Prism}(o.A)},55407:(e,n,t)=>{"use strict";t.d(n,{A:()=>s});var o=t(37953);const r={iconExternalLink:"iconExternalLink_CM8e"};function s(e){let{width:n=13.5,height:t=13.5}=e;return o.createElement("svg",{width:n,height:t,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink},o.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},37129:(e,n,t)=>{"use strict";t.d(n,{A:()=>Nn});var o=t(37953),r=t(68835),s=t(20626),i=t(92347),a=t(72994),c=t(45926),d=t(81809),u=t(14913);const l="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function g(){const e=(0,o.useRef)(null),{action:n}=(0,c.W6)(),t=(0,o.useCallback)((e=>{e.preventDefault();const n=null!=(t=document.querySelector("main:first-of-type"))?t:document.getElementById(l);var t;n&&p(n)}),[]);return(0,u.$)((t=>{let{location:o}=t;e.current&&!o.hash&&"PUSH"===n&&p(e.current)})),{containerRef:e,onClick:t}}const m=(0,d.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function _(e){var n;const t=null!=(n=e.children)?n:m,{containerRef:r,onClick:s}=g();return o.createElement("div",{ref:r,role:"region","aria-label":m},o.createElement("a",(0,a.A)({},e,{href:"#"+l,onClick:s}),t))}var f=t(56168),h=t(83876);const b={skipToContent:"skipToContent_Vg54"};function v(){return o.createElement(_,{className:b.skipToContent})}var y=t(5615),w=t(59768);function k(e){let{width:n=21,height:t=21,color:r="currentColor",strokeWidth:s=1.2,className:i,...c}=e;return o.createElement("svg",(0,a.A)({viewBox:"0 0 15 15",width:n,height:t},c),o.createElement("g",{stroke:r,strokeWidth:s},o.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const x={closeButton:"closeButton_ecLh"};function E(e){return o.createElement("button",(0,a.A)({type:"button","aria-label":(0,d.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,r.A)("clean-btn close",x.closeButton,e.className)}),o.createElement(k,{width:14,height:14,strokeWidth:3.1}))}const S={content:"content_AZj6"};function A(e){const{announcementBar:n}=(0,y.p)(),{content:t}=n;return o.createElement("div",(0,a.A)({},e,{className:(0,r.A)(S.content,e.className),dangerouslySetInnerHTML:{__html:t}}))}const C={announcementBar:"announcementBar_O5ne",announcementBarPlaceholder:"announcementBarPlaceholder__a47",announcementBarClose:"announcementBarClose_RFeM",announcementBarContent:"announcementBarContent_HY65"};function T(){const{announcementBar:e}=(0,y.p)(),{isActive:n,close:t}=(0,w.Mj)();if(!n)return null;const{backgroundColor:r,textColor:s,isCloseable:i}=e;return o.createElement("div",{className:C.announcementBar,style:{backgroundColor:r,color:s},role:"banner"},i&&o.createElement("div",{className:C.announcementBarPlaceholder}),o.createElement(A,{className:C.announcementBarContent}),i&&o.createElement(E,{onClick:t,className:C.announcementBarClose}))}var L=t(47916),R=t(30727);var N=t(30893),P=t(23045);const O=o.createContext(null);function I(e){let{children:n}=e;const t=function(){const e=(0,L.M)(),n=(0,P.YL)(),[t,r]=(0,o.useState)(!1),s=null!==n.component,i=(0,N.ZC)(s);return(0,o.useEffect)((()=>{s&&!i&&r(!0)}),[s,i]),(0,o.useEffect)((()=>{s?e.shown||r(!0):r(!1)}),[e.shown,s]),(0,o.useMemo)((()=>[t,r]),[t])}();return o.createElement(O.Provider,{value:t},n)}function D(e){if(e.component){const n=e.component;return o.createElement(n,e.props)}}function q(){const e=(0,o.useContext)(O);if(!e)throw new N.dV("NavbarSecondaryMenuDisplayProvider");const[n,t]=e,r=(0,o.useCallback)((()=>t(!1)),[t]),s=(0,P.YL)();return(0,o.useMemo)((()=>({shown:n,hide:r,content:D(s)})),[r,s,n])}function M(e){let{header:n,primaryMenu:t,secondaryMenu:s}=e;const{shown:i}=q();return o.createElement("div",{className:"navbar-sidebar"},n,o.createElement("div",{className:(0,r.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},o.createElement("div",{className:"navbar-sidebar__item menu"},t),o.createElement("div",{className:"navbar-sidebar__item menu"},s)))}var j=t(3200),B=t(82182);function F(e){return o.createElement("svg",(0,a.A)({viewBox:"0 0 24 24",width:24,height:24},e),o.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function z(e){return o.createElement("svg",(0,a.A)({viewBox:"0 0 24 24",width:24,height:24},e),o.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const U={toggle:"toggle_Nhsf",toggleButton:"toggleButton_KQsj",darkToggleIcon:"darkToggleIcon_x9vQ",lightToggleIcon:"lightToggleIcon_KkI6",toggleButtonDisabled:"toggleButtonDisabled_gRAo"};function $(e){let{className:n,buttonClassName:t,value:s,onChange:i}=e;const a=(0,B.A)(),c=(0,d.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===s?(0,d.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,d.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return o.createElement("div",{className:(0,r.A)(U.toggle,n)},o.createElement("button",{className:(0,r.A)("clean-btn",U.toggleButton,!a&&U.toggleButtonDisabled,t),type:"button",onClick:()=>i("dark"===s?"light":"dark"),disabled:!a,title:c,"aria-label":c,"aria-live":"polite"},o.createElement(F,{className:(0,r.A)(U.toggleIcon,U.lightToggleIcon)}),o.createElement(z,{className:(0,r.A)(U.toggleIcon,U.darkToggleIcon)})))}const G=o.memo($),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_vn02"};function V(e){let{className:n}=e;const t=(0,y.p)().navbar.style,r=(0,y.p)().colorMode.disableSwitch,{colorMode:s,setColorMode:i}=(0,j.G)();return r?null:o.createElement(G,{className:n,buttonClassName:"dark"===t?H.darkNavbarColorModeToggle:void 0,value:s,onChange:i})}var W=t(43157);function K(){return o.createElement(W.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,L.M)();return o.createElement("button",{type:"button","aria-label":(0,d.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},o.createElement(k,{color:"var(--ifm-color-emphasis-600)"}))}function Q(){return o.createElement("div",{className:"navbar-sidebar__brand"},o.createElement(K,null),o.createElement(V,{className:"margin-right--md"}),o.createElement(Y,null))}var X=t(75040),Z=t(90900),J=t(53021),ee=t(86491),ne=t(55407);function te(e){let{activeBasePath:n,activeBaseRegex:t,to:r,href:s,label:i,html:c,isDropdownLink:d,prependBaseUrlToHref:u,...l}=e;const p=(0,Z.A)(r),g=(0,Z.A)(n),m=(0,Z.A)(s,{forcePrependBaseUrl:!0}),_=i&&s&&!(0,J.A)(s),f=c?{dangerouslySetInnerHTML:{__html:c}}:{children:o.createElement(o.Fragment,null,i,_&&o.createElement(ne.A,d&&{width:12,height:12}))};return s?o.createElement(X.A,(0,a.A)({href:u?m:s},l,f)):o.createElement(X.A,(0,a.A)({to:p,isNavLink:!0},(n||t)&&{isActive:(e,n)=>t?(0,ee.G)(t,n.pathname):n.pathname.startsWith(g)},l,f))}function oe(e){let{className:n,isDropdownItem:t=!1,...s}=e;const i=o.createElement(te,(0,a.A)({className:(0,r.A)(t?"dropdown__link":"navbar__item navbar__link",n),isDropdownLink:t},s));return t?o.createElement("li",null,i):i}function re(e){let{className:n,isDropdownItem:t,...s}=e;return o.createElement("li",{className:"menu__list-item"},o.createElement(te,(0,a.A)({className:(0,r.A)("menu__link",n)},s)))}function se(e){var n;let{mobile:t=!1,position:r,...s}=e;const i=t?re:oe;return o.createElement(i,(0,a.A)({},s,{activeClassName:null!=(n=s.activeClassName)?n:t?"menu__link--active":"navbar__link--active"}))}var ie=t(79627),ae=t(74378),ce=t(77815);function de(e,n){return e.some((e=>function(e,n){return!!(0,ae.ys)(e.to,n)||!!(0,ee.G)(e.activeBaseRegex,n)||!(!e.activeBasePath||!n.startsWith(e.activeBasePath))}(e,n)))}function ue(e){var n;let{items:t,position:s,className:i,onClick:c,...d}=e;const u=(0,o.useRef)(null),[l,p]=(0,o.useState)(!1);return(0,o.useEffect)((()=>{const e=e=>{u.current&&!u.current.contains(e.target)&&p(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[u]),o.createElement("div",{ref:u,className:(0,r.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===s,"dropdown--show":l})},o.createElement(te,(0,a.A)({"aria-haspopup":"true","aria-expanded":l,role:"button",href:d.to?void 0:"#",className:(0,r.A)("navbar__link",i)},d,{onClick:d.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),p(!l))}}),null!=(n=d.children)?n:d.label),o.createElement("ul",{className:"dropdown__menu"},t.map(((e,n)=>o.createElement($e,(0,a.A)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:n}))))))}function le(e){var n;let{items:t,className:s,position:i,onClick:d,...u}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:n}=(0,c.zy)();return n.replace(e,"/")}(),p=de(t,l),{collapsed:g,toggleCollapsed:m,setCollapsed:_}=(0,ie.u)({initialState:()=>!p});return(0,o.useEffect)((()=>{p&&_(!p)}),[l,p,_]),o.createElement("li",{className:(0,r.A)("menu__list-item",{"menu__list-item--collapsed":g})},o.createElement(te,(0,a.A)({role:"button",className:(0,r.A)("menu__link menu__link--sublist menu__link--sublist-caret",s)},u,{onClick:e=>{e.preventDefault(),m()}}),null!=(n=u.children)?n:u.label),o.createElement(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g},t.map(((e,n)=>o.createElement($e,(0,a.A)({mobile:!0,isDropdownItem:!0,onClick:d,activeClassName:"menu__link--active"},e,{key:n}))))))}function pe(e){let{mobile:n=!1,...t}=e;const r=n?le:ue;return o.createElement(r,t)}var ge=t(70892);function me(e){let{width:n=20,height:t=20,...r}=e;return o.createElement("svg",(0,a.A)({viewBox:"0 0 24 24",width:n,height:t,"aria-hidden":!0},r),o.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const _e="iconLanguage_UrR7";function fe(){return o.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},o.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var he=t(86004),be=["translations"];function ve(){return ve=Object.assign||function(e){for(var n=1;ne.length)&&(n=e.length);for(var t=0,o=new Array(n);t=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var xe="Ctrl";var Ee=o.forwardRef((function(e,n){var t=e.translations,r=void 0===t?{}:t,s=ke(e,be),i=r.buttonText,a=void 0===i?"Search":i,c=r.buttonAriaLabel,d=void 0===c?"Search":c,u=ye((0,o.useState)(null),2),l=u[0],p=u[1];return(0,o.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(xe))}),[]),o.createElement("button",ve({type:"button",className:"DocSearch DocSearch-Button","aria-label":d},s,{ref:n}),o.createElement("span",{className:"DocSearch-Button-Container"},o.createElement(he.W,null),o.createElement("span",{className:"DocSearch-Button-Placeholder"},a)),o.createElement("span",{className:"DocSearch-Button-Keys"},null!==l&&o.createElement(o.Fragment,null,o.createElement("kbd",{className:"DocSearch-Button-Key"},l===xe?o.createElement(fe,null):l),o.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Se=t(92549),Ae=t(2468),Ce=t(93901),Te=t(49728);var Le=t(88705);const Re={button:{buttonText:(0,d.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,d.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,d.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,d.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,d.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,d.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,d.T)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,d.T)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,d.T)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,d.T)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,d.T)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,d.T)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,d.T)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,d.T)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,d.T)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,d.T)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,d.T)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,d.T)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,d.T)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,d.T)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,d.T)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,d.T)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,d.T)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,d.T)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,d.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,d.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,d.T)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Ne=null;function Pe(e){let{hit:n,children:t}=e;return o.createElement(X.A,{to:n.url},t)}function Oe(e){let{state:n,onClose:t}=e;const r=(0,Ae.w)();return o.createElement(X.A,{to:r(n.query),onClick:t},o.createElement(d.A,{id:"theme.SearchBar.seeAll",values:{count:n.context.nbHits}},"See all {count} results"))}function Ie(e){var n,r;let{contextualSearch:s,externalUrlRegex:i,...d}=e;const{siteMetadata:u}=(0,ce.A)(),l=(0,Ce.C)(),p=function(){const{locale:e,tags:n}=(0,Te.af)();return["language:"+e,n.map((e=>"docusaurus_tag:"+e))]}(),g=null!=(n=null==(r=d.searchParameters)?void 0:r.facetFilters)?n:[],m=s?function(e,n){const t=e=>"string"==typeof e?[e]:e;return[...t(e),...t(n)]}(p,g):g,_={...d.searchParameters,facetFilters:m},f=(0,c.W6)(),h=(0,o.useRef)(null),b=(0,o.useRef)(null),[v,y]=(0,o.useState)(!1),[w,k]=(0,o.useState)(void 0),x=(0,o.useCallback)((()=>Ne?Promise.resolve():Promise.all([t.e(36894).then(t.bind(t,36894)),Promise.all([t.e(71869),t.e(25009)]).then(t.bind(t,25009)),Promise.all([t.e(71869),t.e(53217)]).then(t.bind(t,53217))]).then((e=>{let[{DocSearchModal:n}]=e;Ne=n}))),[]),E=(0,o.useCallback)((()=>{x().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),y(!0)}))}),[x,y]),S=(0,o.useCallback)((()=>{var e;y(!1),null==(e=h.current)||e.remove()}),[y]),A=(0,o.useCallback)((e=>{x().then((()=>{y(!0),k(e.key)}))}),[x,y,k]),C=(0,o.useRef)({navigate(e){let{itemUrl:n}=e;(0,ee.G)(i,n)?window.location.href=n:f.push(n)}}).current,T=(0,o.useRef)((e=>d.transformItems?d.transformItems(e):e.map((e=>({...e,url:l(e.url)}))))).current,L=(0,o.useMemo)((()=>e=>o.createElement(Oe,(0,a.A)({},e,{onClose:S}))),[S]),R=(0,o.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",u.docusaurusVersion),e)),[u.docusaurusVersion]);return function(e){var n=e.isOpen,t=e.onOpen,r=e.onClose,s=e.onInput,i=e.searchButtonRef;o.useEffect((function(){function e(e){var o;(27===e.keyCode&&n||"k"===(null===(o=e.key)||void 0===o?void 0:o.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var n=e.target,t=n.tagName;return n.isContentEditable||"INPUT"===t||"SELECT"===t||"TEXTAREA"===t}(e)&&"/"===e.key&&!n)&&(e.preventDefault(),n?r():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||t()),i&&i.current===document.activeElement&&s&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&s(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[n,t,r,s,i])}({isOpen:v,onOpen:E,onClose:S,onInput:A,searchButtonRef:b}),o.createElement(o.Fragment,null,o.createElement(Se.A,null,o.createElement("link",{rel:"preconnect",href:"https://"+d.appId+"-dsn.algolia.net",crossOrigin:"anonymous"})),o.createElement(Ee,{onTouchStart:x,onFocus:x,onMouseOver:x,onClick:E,ref:b,translations:Re.button}),v&&Ne&&h.current&&(0,Le.createPortal)(o.createElement(Ne,(0,a.A)({onClose:S,initialScrollY:window.scrollY,initialQuery:w,navigator:C,transformItems:T,hitComponent:Pe,transformSearchClient:R},d.searchPagePath&&{resultsFooterComponent:L},d,{searchParameters:_,placeholder:Re.placeholder,translations:Re.modal})),h.current))}function De(){const{siteConfig:e}=(0,ce.A)();return o.createElement(Ie,e.themeConfig.algolia)}const qe={searchBox:"searchBox_NmYg"};function Me(e){let{children:n,className:t}=e;return o.createElement("div",{className:(0,r.A)(t,qe.searchBox)},n)}var je=t(82952),Be=t(37773);var Fe=t(17182);const ze=e=>e.docs.find((n=>n.id===e.mainDocId));const Ue={default:se,localeDropdown:function(e){let{mobile:n,dropdownItemsBefore:t,dropdownItemsAfter:r,...s}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:l}}=(0,ce.A)(),p=(0,ge.o)(),{search:g,hash:m}=(0,c.zy)(),_=[...t,...u.map((e=>{const t=""+("pathname://"+p.createUrl({locale:e,fullyQualified:!1}))+g+m;return{label:l[e].label,lang:l[e].htmlLang,to:t,target:"_self",autoAddBaseUrl:!1,className:e===i?n?"menu__link--active":"dropdown__link--active":""}})),...r],f=n?(0,d.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):l[i].label;return o.createElement(pe,(0,a.A)({},s,{mobile:n,label:o.createElement(o.Fragment,null,o.createElement(me,{className:_e}),f),items:_}))},search:function(e){let{mobile:n,className:t}=e;return n?null:o.createElement(Me,{className:t},o.createElement(De,null))},dropdown:pe,html:function(e){let{value:n,className:t,mobile:s=!1,isDropdownItem:i=!1}=e;const a=i?"li":"div";return o.createElement(a,{className:(0,r.A)({navbar__item:!s&&!i,"menu__list-item":s},t),dangerouslySetInnerHTML:{__html:n}})},doc:function(e){let{docId:n,label:t,docsPluginId:r,...s}=e;const{activeDoc:i}=(0,je.zK)(r),c=(0,Be.QB)(n,r);return null===c?null:o.createElement(se,(0,a.A)({exact:!0},s,{isActive:()=>(null==i?void 0:i.path)===c.path||!(null==i||!i.sidebar)&&i.sidebar===c.sidebar,label:null!=t?t:c.id,to:c.path}))},docSidebar:function(e){let{sidebarId:n,label:t,docsPluginId:r,...s}=e;const{activeDoc:i}=(0,je.zK)(r),c=(0,Be.fW)(n,r).link;if(!c)throw new Error('DocSidebarNavbarItem: Sidebar with ID "'+n+"\" doesn't have anything to be linked to.");return o.createElement(se,(0,a.A)({exact:!0},s,{isActive:()=>(null==i?void 0:i.sidebar)===n,label:null!=t?t:c.label,to:c.path}))},docsVersion:function(e){let{label:n,to:t,docsPluginId:r,...s}=e;const i=(0,Be.Vd)(r)[0],c=null!=n?n:i.label,d=null!=t?t:(e=>e.docs.find((n=>n.id===e.mainDocId)))(i).path;return o.createElement(se,(0,a.A)({},s,{label:c,to:d}))},docsVersionDropdown:function(e){let{mobile:n,docsPluginId:t,dropdownActiveClassDisabled:r,dropdownItemsBefore:s,dropdownItemsAfter:i,...u}=e;const{search:l,hash:p}=(0,c.zy)(),g=(0,je.zK)(t),m=(0,je.jh)(t),{savePreferredVersionName:_}=(0,Fe.g1)(t),f=[...s,...m.map((e=>{var n;const t=null!=(n=g.alternateDocVersions[e.name])?n:ze(e);return{label:e.label,to:""+t.path+l+p,isActive:()=>e===g.activeVersion,onClick:()=>_(e.name)}})),...i],h=(0,Be.Vd)(t)[0],b=n&&f.length>1?(0,d.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,v=n&&f.length>1?void 0:ze(h).path;return f.length<=1?o.createElement(se,(0,a.A)({},u,{mobile:n,label:b,to:v,isActive:r?()=>!1:void 0})):o.createElement(pe,(0,a.A)({},u,{mobile:n,label:b,to:v,items:f,isActive:r?()=>!1:void 0}))}};function $e(e){let{type:n,...t}=e;const r=function(e,n){return e&&"default"!==e?e:"items"in n?"dropdown":"default"}(n,t),s=Ue[r];if(!s)throw new Error('No NavbarItem component found for type "'+n+'".');return o.createElement(s,t)}function Ge(){const e=(0,L.M)(),n=(0,y.p)().navbar.items;return o.createElement("ul",{className:"menu__list"},n.map(((n,t)=>o.createElement($e,(0,a.A)({mobile:!0},n,{onClick:()=>e.toggle(),key:t})))))}function He(e){return o.createElement("button",(0,a.A)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),o.createElement(d.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Ve(){const e=0===(0,y.p)().navbar.items.length,n=q();return o.createElement(o.Fragment,null,!e&&o.createElement(He,{onClick:()=>n.hide()}),n.content)}function We(){const e=(0,L.M)();var n;return void 0===(n=e.shown)&&(n=!0),(0,o.useEffect)((()=>(document.body.style.overflow=n?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[n]),e.shouldRender?o.createElement(M,{header:o.createElement(Q,null),primaryMenu:o.createElement(Ge,null),secondaryMenu:o.createElement(Ve,null)}):null}const Ke={navbarHideable:"navbarHideable__8sl",navbarHidden:"navbarHidden_mYdD"};function Ye(e){return o.createElement("div",(0,a.A)({role:"presentation"},e,{className:(0,r.A)("navbar-sidebar__backdrop",e.className)}))}function Qe(e){let{children:n}=e;const{navbar:{hideOnScroll:t,style:s}}=(0,y.p)(),i=(0,L.M)(),{navbarRef:a,isNavbarVisible:c}=function(e){const[n,t]=(0,o.useState)(e),r=(0,o.useRef)(!1),s=(0,o.useRef)(0),i=(0,o.useCallback)((e=>{null!==e&&(s.current=e.getBoundingClientRect().height)}),[]);return(0,R.Mq)(((n,o)=>{let{scrollY:i}=n;if(!e)return;if(i=a?t(!1):i+d{if(!e)return;const o=n.location.hash;if(o?document.getElementById(o.substring(1)):void 0)return r.current=!0,void t(!1);t(!0)})),{navbarRef:i,isNavbarVisible:n}}(t);return o.createElement("nav",{ref:a,"aria-label":(0,d.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,r.A)("navbar","navbar--fixed-top",t&&[Ke.navbarHideable,!c&&Ke.navbarHidden],{"navbar--dark":"dark"===s,"navbar--primary":"primary"===s,"navbar-sidebar--show":i.shown})},n,o.createElement(Ye,{onClick:i.toggle}),o.createElement(We,null))}var Xe=t(16097);const Ze={errorBoundaryError:"errorBoundaryError_Ag75"};function Je(e){return o.createElement("button",(0,a.A)({type:"button"},e),o.createElement(d.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function en(e){let{error:n}=e;const t=(0,Xe.getErrorCausalChain)(n).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{className:Ze.errorBoundaryError},t)}class nn extends o.Component{componentDidCatch(e,n){throw this.props.onError(e,n)}render(){return this.props.children}}const tn="right";function on(e){let{width:n=30,height:t=30,className:r,...s}=e;return o.createElement("svg",(0,a.A)({className:r,width:n,height:t,viewBox:"0 0 30 30","aria-hidden":"true"},s),o.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function rn(){const{toggle:e,shown:n}=(0,L.M)();return o.createElement("button",{onClick:e,"aria-label":(0,d.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":n,className:"navbar__toggle clean-btn",type:"button"},o.createElement(on,null))}const sn={colorModeToggle:"colorModeToggle_GocH"};function an(e){let{items:n}=e;return o.createElement(o.Fragment,null,n.map(((e,n)=>o.createElement(nn,{key:n,onError:n=>new Error("A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n"+JSON.stringify(e,null,2),{cause:n})},o.createElement($e,e)))))}function cn(e){let{left:n,right:t}=e;return o.createElement("div",{className:"navbar__inner"},o.createElement("div",{className:"navbar__items"},n),o.createElement("div",{className:"navbar__items navbar__items--right"},t))}function dn(){const e=(0,L.M)(),n=(0,y.p)().navbar.items,[t,r]=function(e){function n(e){var n;return"left"===(null!=(n=e.position)?n:tn)}return[e.filter(n),e.filter((e=>!n(e)))]}(n),s=n.find((e=>"search"===e.type));return o.createElement(cn,{left:o.createElement(o.Fragment,null,!e.disabled&&o.createElement(rn,null),o.createElement(K,null),o.createElement(an,{items:t})),right:o.createElement(o.Fragment,null,o.createElement(an,{items:r}),o.createElement(V,{className:sn.colorModeToggle}),!s&&o.createElement(Me,null,o.createElement(De,null)))})}function un(){return o.createElement(Qe,null,o.createElement(dn,null))}function ln(e){let{item:n}=e;const{to:t,href:r,label:s,prependBaseUrlToHref:i,...c}=n,d=(0,Z.A)(t),u=(0,Z.A)(r,{forcePrependBaseUrl:!0});return o.createElement(X.A,(0,a.A)({className:"footer__link-item"},r?{href:i?u:r}:{to:d},c),s,r&&!(0,J.A)(r)&&o.createElement(ne.A,null))}function pn(e){var n;let{item:t}=e;return t.html?o.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):o.createElement("li",{key:null!=(n=t.href)?n:t.to,className:"footer__item"},o.createElement(ln,{item:t}))}function gn(e){let{column:n}=e;return o.createElement("div",{className:"col footer__col"},o.createElement("div",{className:"footer__title"},n.title),o.createElement("ul",{className:"footer__items clean-list"},n.items.map(((e,n)=>o.createElement(pn,{key:n,item:e})))))}function mn(e){let{columns:n}=e;return o.createElement("div",{className:"row footer__links"},n.map(((e,n)=>o.createElement(gn,{key:n,column:e}))))}function _n(){return o.createElement("span",{className:"footer__link-separator"},"\xb7")}function fn(e){let{item:n}=e;return n.html?o.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:n.html}}):o.createElement(ln,{item:n})}function hn(e){let{links:n}=e;return o.createElement("div",{className:"footer__links text--center"},o.createElement("div",{className:"footer__links"},n.map(((e,t)=>o.createElement(o.Fragment,{key:t},o.createElement(fn,{item:e}),n.length!==t+1&&o.createElement(_n,null))))))}function bn(e){let{links:n}=e;return function(e){return"title"in e[0]}(n)?o.createElement(mn,{columns:n}):o.createElement(hn,{links:n})}var vn=t(41810);const yn={footerLogoLink:"footerLogoLink_sbI4"};function wn(e){var n;let{logo:t}=e;const{withBaseUrl:s}=(0,Z.h)(),i={light:s(t.src),dark:s(null!=(n=t.srcDark)?n:t.src)};return o.createElement(vn.A,{className:(0,r.A)("footer__logo",t.className),alt:t.alt,sources:i,width:t.width,height:t.height,style:t.style})}function kn(e){let{logo:n}=e;return n.href?o.createElement(X.A,{href:n.href,className:yn.footerLogoLink,target:n.target},o.createElement(wn,{logo:n})):o.createElement(wn,{logo:n})}function xn(e){let{copyright:n}=e;return o.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:n}})}function En(e){let{style:n,links:t,logo:s,copyright:i}=e;return o.createElement("footer",{className:(0,r.A)("footer",{"footer--dark":"dark"===n})},o.createElement("div",{className:"container container-fluid"},t,(s||i)&&o.createElement("div",{className:"footer__bottom text--center"},s&&o.createElement("div",{className:"margin-bottom--sm"},s),i)))}function Sn(){const{footer:e}=(0,y.p)();if(!e)return null;const{copyright:n,links:t,logo:r,style:s}=e;return o.createElement(En,{style:s,links:t&&t.length>0&&o.createElement(bn,{links:t}),logo:r&&o.createElement(kn,{logo:r}),copyright:n&&o.createElement(xn,{copyright:n})})}const An=o.memo(Sn),Cn=(0,N.fM)([j.a,w.oq,R.Tv,Fe.VQ,i.Jx,function(e){let{children:n}=e;return o.createElement(P.y_,null,o.createElement(L.e,null,o.createElement(I,null,n)))}]);function Tn(e){let{children:n}=e;return o.createElement(Cn,null,n)}function Ln(e){let{error:n,tryAgain:t}=e;return o.createElement("main",{className:"container margin-vert--xl"},o.createElement("div",{className:"row"},o.createElement("div",{className:"col col--6 col--offset-3"},o.createElement("h1",{className:"hero__title"},o.createElement(d.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),o.createElement("div",{className:"margin-vert--lg"},o.createElement(Je,{onClick:t,className:"button button--primary shadow--lw"})),o.createElement("hr",null),o.createElement("div",{className:"margin-vert--md"},o.createElement(en,{error:n})))))}const Rn={mainWrapper:"mainWrapper_KqcX"};function Nn(e){const{children:n,noFooter:t,wrapperClassName:a,title:c,description:d}=e;return(0,h.J)(),o.createElement(Tn,null,o.createElement(i.be,{title:c,description:d}),o.createElement(v,null),o.createElement(T,null),o.createElement(un,null),o.createElement("div",{id:l,className:(0,r.A)(f.G.wrapper.main,Rn.mainWrapper,a)},o.createElement(s.A,{fallback:e=>o.createElement(Ln,e)},n)),!t&&o.createElement(An,null))}},43157:(e,n,t)=>{"use strict";t.d(n,{A:()=>l});var o=t(72994),r=t(37953),s=t(75040),i=t(90900),a=t(77815),c=t(5615),d=t(41810);function u(e){let{logo:n,alt:t,imageClassName:o}=e;const s={light:(0,i.A)(n.src),dark:(0,i.A)(n.srcDark||n.src)},a=r.createElement(d.A,{className:n.className,sources:s,height:n.height,width:n.width,alt:t,style:n.style});return o?r.createElement("div",{className:o},a):a}function l(e){var n;const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:d,logo:l}}=(0,c.p)(),{imageClassName:p,titleClassName:g,...m}=e,_=(0,i.A)((null==l?void 0:l.href)||"/"),f=d?"":t,h=null!=(n=null==l?void 0:l.alt)?n:f;return r.createElement(s.A,(0,o.A)({to:_},m,(null==l?void 0:l.target)&&{target:l.target}),l&&r.createElement(u,{logo:l,alt:h,imageClassName:p}),null!=d&&r.createElement("b",{className:g},d))}},50675:(e,n,t)=>{"use strict";t.d(n,{A:()=>s});var o=t(37953),r=t(92549);function s(e){let{locale:n,version:t,tag:s}=e;const i=n;return o.createElement(r.A,null,n&&o.createElement("meta",{name:"docusaurus_locale",content:n}),t&&o.createElement("meta",{name:"docusaurus_version",content:t}),s&&o.createElement("meta",{name:"docusaurus_tag",content:s}),i&&o.createElement("meta",{name:"docsearch:language",content:i}),t&&o.createElement("meta",{name:"docsearch:version",content:t}),s&&o.createElement("meta",{name:"docsearch:docusaurus_tag",content:s}))}},41810:(e,n,t)=>{"use strict";t.d(n,{A:()=>d});var o=t(72994),r=t(37953),s=t(68835),i=t(82182),a=t(3200);const c={themedImage:"themedImage_xN_b","themedImage--light":"themedImage--light_zIAV","themedImage--dark":"themedImage--dark_sQmx"};function d(e){const n=(0,i.A)(),{colorMode:t}=(0,a.G)(),{sources:d,className:u,alt:l,...p}=e,g=n?"dark"===t?["dark"]:["light"]:["light","dark"];return r.createElement(r.Fragment,null,g.map((e=>r.createElement("img",(0,o.A)({key:e,src:d[e],alt:l,className:(0,s.A)(c.themedImage,c["themedImage--"+e],u)},p)))))}},79627:(e,n,t)=>{"use strict";t.d(n,{N:()=>f,u:()=>c});var o=t(72994),r=t(37953),s=t(59536),i=t(47920);const a="ease-in-out";function c(e){let{initialState:n}=e;const[t,o]=(0,r.useState)(null!=n&&n),s=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:t,setCollapsed:o,toggleCollapsed:s}}const d={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function l(e,n){const t=n?d:u;e.style.display=t.display,e.style.overflow=t.overflow,e.style.height=t.height}function p(e){let{collapsibleRef:n,collapsed:t,animation:o}=e;const s=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=n.current;function r(){var n,t;const r=e.scrollHeight,s=null!=(n=null==o?void 0:o.duration)?n:function(e){if((0,i.O)())return 1;const n=e/36;return Math.round(10*(4+15*n**.25+n/5))}(r);return{transition:"height "+s+"ms "+(null!=(t=null==o?void 0:o.easing)?t:a),height:r+"px"}}function c(){const n=r();e.style.transition=n.transition,e.style.height=n.height}if(!s.current)return l(e,t),void(s.current=!0);return e.style.willChange="height",function(){const n=requestAnimationFrame((()=>{t?(c(),requestAnimationFrame((()=>{e.style.height=d.height,e.style.overflow=d.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{c()})))}));return()=>cancelAnimationFrame(n)}()}),[n,t,o])}function g(e){if(!s.A.canUseDOM)return e?d:u}function m(e){let{as:n="div",collapsed:t,children:o,animation:s,onCollapseTransitionEnd:i,className:a,disableSSRStyle:c}=e;const d=(0,r.useRef)(null);return p({collapsibleRef:d,collapsed:t,animation:s}),r.createElement(n,{ref:d,style:c?void 0:g(t),onTransitionEnd:e=>{"height"===e.propertyName&&(l(d.current,t),null==i||i(t))},className:a},o)}function _(e){let{collapsed:n,...t}=e;const[s,i]=(0,r.useState)(!n),[a,c]=(0,r.useState)(n);return(0,r.useLayoutEffect)((()=>{n||i(!0)}),[n]),(0,r.useLayoutEffect)((()=>{s&&c(n)}),[s,n]),s?r.createElement(m,(0,o.A)({},t,{collapsed:a})):null}function f(e){let{lazy:n,...t}=e;const o=n?_:m;return r.createElement(o,t)}},59768:(e,n,t)=>{"use strict";t.d(n,{Mj:()=>m,oq:()=>g});var o=t(37953),r=t(82182),s=t(15323),i=t(30893),a=t(5615);const c=(0,s.Wf)("docusaurus.announcement.dismiss"),d=(0,s.Wf)("docusaurus.announcement.id"),u=()=>"true"===c.get(),l=e=>c.set(String(e)),p=o.createContext(null);function g(e){let{children:n}=e;const t=function(){const{announcementBar:e}=(0,a.p)(),n=(0,r.A)(),[t,s]=(0,o.useState)((()=>!!n&&u()));(0,o.useEffect)((()=>{s(u())}),[]);const i=(0,o.useCallback)((()=>{l(!0),s(!0)}),[]);return(0,o.useEffect)((()=>{if(!e)return;const{id:n}=e;let t=d.get();"annoucement-bar"===t&&(t="announcement-bar");const o=n!==t;d.set(n),o&&l(!1),!o&&u()||s(!1)}),[e]),(0,o.useMemo)((()=>({isActive:!!e&&!t,close:i})),[e,t,i])}();return o.createElement(p.Provider,{value:t},n)}function m(){const e=(0,o.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},3200:(e,n,t)=>{"use strict";t.d(n,{G:()=>f,a:()=>_});var o=t(37953),r=t(59536),s=t(30893),i=t(15323),a=t(5615);const c=o.createContext(void 0),d="theme",u=(0,i.Wf)(d),l={light:"light",dark:"dark"},p=e=>e===l.dark?l.dark:l.light,g=e=>r.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function _(e){let{children:n}=e;const t=function(){const{colorMode:{defaultMode:e,disableSwitch:n,respectPrefersColorScheme:t}}=(0,a.p)(),[r,s]=(0,o.useState)(g(e));(0,o.useEffect)((()=>{n&&u.del()}),[n]);const i=(0,o.useCallback)((function(n,o){void 0===o&&(o={});const{persist:r=!0}=o;n?(s(n),r&&m(n)):(s(t?window.matchMedia("(prefers-color-scheme: dark)").matches?l.dark:l.light:e),u.del())}),[t,e]);(0,o.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(r))}),[r]),(0,o.useEffect)((()=>{if(n)return;const e=e=>{if(e.key!==d)return;const n=u.get();null!==n&&i(p(n))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[n,i]);const c=(0,o.useRef)(!1);return(0,o.useEffect)((()=>{if(n&&!t)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),o=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:i(null)};return e.addListener(o),()=>e.removeListener(o)}),[i,n,t]),(0,o.useMemo)((()=>({colorMode:r,setColorMode:i,get isDarkTheme(){return r===l.dark},setLightTheme(){i(l.light)},setDarkTheme(){i(l.dark)}})),[r,i])}();return o.createElement(c.Provider,{value:t},n)}function f(){const e=(0,o.useContext)(c);if(null==e)throw new s.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},17182:(e,n,t)=>{"use strict";t.d(n,{VQ:()=>f,XK:()=>v,g1:()=>b});var o=t(37953),r=t(82952),s=t(28230),i=t(5615),a=t(37773),c=t(30893),d=t(15323);const u=e=>"docs-preferred-version-"+e,l={save:(e,n,t)=>{(0,d.Wf)(u(e),{persistence:n}).set(t)},read:(e,n)=>(0,d.Wf)(u(e),{persistence:n}).get(),clear:(e,n)=>{(0,d.Wf)(u(e),{persistence:n}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=o.createContext(null);function m(){const e=(0,r.Gy)(),n=(0,i.p)().docs.versionPersistence,t=(0,o.useMemo)((()=>Object.keys(e)),[e]),[s,a]=(0,o.useState)((()=>p(t)));(0,o.useEffect)((()=>{a(function(e){let{pluginIds:n,versionPersistence:t,allDocsData:o}=e;function r(e){const n=l.read(e,t);return o[e].versions.some((e=>e.name===n))?{preferredVersionName:n}:(l.clear(e,t),{preferredVersionName:null})}return Object.fromEntries(n.map((e=>[e,r(e)])))}({allDocsData:e,versionPersistence:n,pluginIds:t}))}),[e,n,t]);return[s,(0,o.useMemo)((()=>({savePreferredVersion:function(e,t){l.save(e,n,t),a((n=>({...n,[e]:{preferredVersionName:t}})))}})),[n])]}function _(e){let{children:n}=e;const t=m();return o.createElement(g.Provider,{value:t},n)}function f(e){let{children:n}=e;return a.C5?o.createElement(_,null,n):o.createElement(o.Fragment,null,n)}function h(){const e=(0,o.useContext)(g);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function b(e){var n;void 0===e&&(e=s.W);const t=(0,r.ht)(e),[i,a]=h(),{preferredVersionName:c}=i[e];return{preferredVersion:null!=(n=t.versions.find((e=>e.name===c)))?n:null,savePreferredVersionName:(0,o.useCallback)((n=>{a.savePreferredVersion(e,n)}),[a,e])}}function v(){const e=(0,r.Gy)(),[n]=h();function t(t){var o;const r=e[t],{preferredVersionName:s}=n[t];return null!=(o=r.versions.find((e=>e.name===s)))?o:null}const o=Object.keys(e);return Object.fromEntries(o.map((e=>[e,t(e)])))}},59969:(e,n,t)=>{"use strict";t.d(n,{V:()=>a,t:()=>c});var o=t(37953),r=t(30893);const s=Symbol("EmptyContext"),i=o.createContext(s);function a(e){let{children:n,name:t,items:r}=e;const s=(0,o.useMemo)((()=>t&&r?{name:t,items:r}:null),[t,r]);return o.createElement(i.Provider,{value:s},n)}function c(){const e=(0,o.useContext)(i);if(e===s)throw new r.dV("DocsSidebarProvider");return e}},47916:(e,n,t)=>{"use strict";t.d(n,{M:()=>p,e:()=>l});var o=t(37953),r=t(23045),s=t(66862),i=t(21544),a=t(5615),c=t(30893);const d=o.createContext(void 0);function u(){const e=function(){const e=(0,r.YL)(),{items:n}=(0,a.p)().navbar;return 0===n.length&&!e.component}(),n=(0,s.l)(),t=!e&&"mobile"===n,[c,d]=(0,o.useState)(!1);(0,i.$Z)((()=>{if(c)return d(!1),!1}));const u=(0,o.useCallback)((()=>{d((e=>!e))}),[]);return(0,o.useEffect)((()=>{"desktop"===n&&d(!1)}),[n]),(0,o.useMemo)((()=>({disabled:e,shouldRender:t,toggle:u,shown:c})),[e,t,u,c])}function l(e){let{children:n}=e;const t=u();return o.createElement(d.Provider,{value:t},n)}function p(){const e=o.useContext(d);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},23045:(e,n,t)=>{"use strict";t.d(n,{GX:()=>c,YL:()=>a,y_:()=>i});var o=t(37953),r=t(30893);const s=o.createContext(null);function i(e){let{children:n}=e;const t=(0,o.useState)({component:null,props:null});return o.createElement(s.Provider,{value:t},n)}function a(){const e=(0,o.useContext)(s);if(!e)throw new r.dV("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:n,props:t}=e;const i=(0,o.useContext)(s);if(!i)throw new r.dV("NavbarSecondaryMenuContentProvider");const[,a]=i,c=(0,r.Be)(t);return(0,o.useEffect)((()=>{a({component:n,props:c})}),[a,n,c]),(0,o.useEffect)((()=>()=>a({component:null,props:null})),[a]),null}},83876:(e,n,t)=>{"use strict";t.d(n,{w:()=>r,J:()=>s});var o=t(37953);const r="navigation-with-keyboard";function s(){(0,o.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(r),"mousedown"===e.type&&document.body.classList.remove(r)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(r),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},2468:(e,n,t)=>{"use strict";t.d(n,{b:()=>a,w:()=>c});var o=t(37953),r=t(77815),s=t(21544);const i="q";function a(){return(0,s.l)(i)}function c(){const{siteConfig:{baseUrl:e,themeConfig:n}}=(0,r.A)(),{algolia:{searchPagePath:t}}=n;return(0,o.useCallback)((n=>""+e+t+"?"+i+"="+encodeURIComponent(n)),[e,t])}},66862:(e,n,t)=>{"use strict";t.d(n,{l:()=>d});var o=t(37953),r=t(59536);const s={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function a(){return r.A.canUseDOM?window.innerWidth>i?s.desktop:s.mobile:s.ssr}const c=!1;function d(){const[e,n]=(0,o.useState)((()=>c?"ssr":a()));return(0,o.useEffect)((()=>{function e(){n(a())}const t=c?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(t)}}),[]),e}},56168:(e,n,t)=>{"use strict";t.d(n,{G:()=>o});const o={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>"theme-admonition-"+e},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>"theme-doc-sidebar-item-category-level-"+e,docSidebarItemLinkLevel:e=>"theme-doc-sidebar-item-link-level-"+e},blog:{}}},47920:(e,n,t)=>{"use strict";function o(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}t.d(n,{O:()=>o})},37773:(e,n,t)=>{"use strict";t.d(n,{C5:()=>l,OF:()=>h,QB:()=>y,Vd:()=>b,_o:()=>p,fW:()=>v,mz:()=>w,w8:()=>_});var o=t(37953),r=t(45926),s=t(88562),i=t(82952),a=t(17182),c=t(59969),d=t(8441),u=t(74378);const l=!!i.Gy;function p(e){if(e.href)return e.href;for(const n of e.items){if("link"===n.type)return n.href;if("category"===n.type){const e=p(n);if(e)return e}}}const g=(e,n)=>void 0!==e&&(0,u.ys)(e,n),m=(e,n)=>e.some((e=>_(e,n)));function _(e,n){return"link"===e.type?g(e.href,n):"category"===e.type&&(g(e.href,n)||m(e.items,n))}function f(e){let{sidebarItems:n,pathname:t,onlyCategories:o=!1}=e;const r=[];return function e(n){for(const s of n)if("category"===s.type&&((0,u.ys)(s.href,t)||e(s.items))||"link"===s.type&&(0,u.ys)(s.href,t)){return o&&"category"!==s.type||r.unshift(s),!0}return!1}(n),r}function h(){var e;const n=(0,c.t)(),{pathname:t}=(0,r.zy)();return!1!==(null==(e=(0,i.vT)())?void 0:e.pluginData.breadcrumbs)&&n?f({sidebarItems:n.items,pathname:t}):null}function b(e){const{activeVersion:n}=(0,i.zK)(e),{preferredVersion:t}=(0,a.g1)(e),r=(0,i.r7)(e);return(0,o.useMemo)((()=>(0,d.s)([n,t,r].filter(Boolean))),[n,t,r])}function v(e,n){const t=b(n);return(0,o.useMemo)((()=>{const n=t.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),o=n.find((n=>n[0]===e));if(!o)throw new Error("Can't find any sidebar with id \""+e+'" in version'+(t.length>1?"s":"")+" "+t.map((e=>e.name)).join(", ")+'".\nAvailable sidebar ids are:\n- '+n.map((e=>e[0])).join("\n- "));return o[1]}),[e,t])}function y(e,n){const t=b(n);return(0,o.useMemo)((()=>{const n=t.flatMap((e=>e.docs)),o=n.find((n=>n.id===e));if(!o){if(t.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error("Couldn't find any doc with id \""+e+'" in version'+(t.length>1?"s":"")+' "'+t.map((e=>e.name)).join(", ")+'".\nAvailable doc ids are:\n- '+(0,d.s)(n.map((e=>e.id))).join("\n- "))}return o}),[e,t])}function w(e){let{route:n,versionMetadata:t}=e;const o=(0,r.zy)(),i=n.routes,a=i.find((e=>(0,r.B6)(o.pathname,e)));if(!a)return null;const c=a.sidebar,d=c?t.docsSidebars[c]:void 0;return{docElement:(0,s.v)(i),sidebarName:c,sidebarItems:d}}},32416:(e,n,t)=>{"use strict";t.d(n,{s:()=>r});var o=t(77815);function r(e){const{siteConfig:n}=(0,o.A)(),{title:t,titleDelimiter:r}=n;return null!=e&&e.trim().length?e.trim()+" "+r+" "+t:t}},21544:(e,n,t)=>{"use strict";t.d(n,{$Z:()=>a,aZ:()=>c,l:()=>d});var o=t(37953),r=t(45926),s=t(86872),i=t(30893);function a(e){!function(e){const n=(0,r.W6)(),t=(0,i._q)(e);(0,o.useEffect)((()=>n.block(((e,n)=>t(e,n)))),[n,t])}(((n,t)=>{if("POP"===t)return e(n,t)}))}function c(e){return function(e){const n=(0,r.W6)();return(0,s.useSyncExternalStore)(n.listen,(()=>e(n)),(()=>e(n)))}((n=>null===e?null:new URLSearchParams(n.location.search).get(e)))}function d(e){var n;const t=null!=(n=c(e))?n:"",s=function(){const e=(0,r.W6)();return(0,o.useCallback)(((n,t,o)=>{const r=new URLSearchParams(e.location.search);t?r.set(n,t):r.delete(n),(null!=o&&o.push?e.push:e.replace)({search:r.toString()})}),[e])}();return[t,(0,o.useCallback)(((n,t)=>{s(e,n,t)}),[s,e])]}},8441:(e,n,t)=>{"use strict";function o(e,n){return void 0===n&&(n=(e,n)=>e===n),e.filter(((t,o)=>e.findIndex((e=>n(e,t)))!==o))}function r(e){return Array.from(new Set(e))}t.d(n,{X:()=>o,s:()=>r})},92347:(e,n,t)=>{"use strict";t.d(n,{e3:()=>p,be:()=>u,Jx:()=>g});var o=t(37953),r=t(68835),s=t(92549),i=t(86131);function a(){const e=o.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var c=t(90900),d=t(32416);function u(e){let{title:n,description:t,keywords:r,image:i,children:a}=e;const u=(0,d.s)(n),{withBaseUrl:l}=(0,c.h)(),p=i?l(i,{absolute:!0}):void 0;return o.createElement(s.A,null,n&&o.createElement("title",null,u),n&&o.createElement("meta",{property:"og:title",content:u}),t&&o.createElement("meta",{name:"description",content:t}),t&&o.createElement("meta",{property:"og:description",content:t}),r&&o.createElement("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&o.createElement("meta",{property:"og:image",content:p}),p&&o.createElement("meta",{name:"twitter:image",content:p}),a)}const l=o.createContext(void 0);function p(e){let{className:n,children:t}=e;const i=o.useContext(l),a=(0,r.A)(i,n);return o.createElement(l.Provider,{value:a},o.createElement(s.A,null,o.createElement("html",{className:a})),t)}function g(e){let{children:n}=e;const t=a(),s="plugin-"+t.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"");const i="plugin-id-"+t.plugin.id;return o.createElement(p,{className:(0,r.A)(s,i)},n)}},30893:(e,n,t)=>{"use strict";t.d(n,{Be:()=>c,ZC:()=>i,_q:()=>s,dV:()=>a,fM:()=>d});var o=t(37953);const r=t(59536).A.canUseDOM?o.useLayoutEffect:o.useEffect;function s(e){const n=(0,o.useRef)(e);return r((()=>{n.current=e}),[e]),(0,o.useCallback)((function(){return n.current(...arguments)}),[])}function i(e){const n=(0,o.useRef)();return r((()=>{n.current=e})),n.current}class a extends Error{constructor(e,n){var t,o;super(),this.name="ReactContextError",this.message="Hook "+(null!=(t=null==(o=this.stack)||null==(o=o.split("\n")[1])||null==(o=o.match(/at (?:\w+\.)?(?\w+)/))?void 0:o.groups.name)?t:"")+" is called outside the <"+e+">. "+(null!=n?n:"")}}function c(e){const n=Object.entries(e);return n.sort(((e,n)=>e[0].localeCompare(n[0]))),(0,o.useMemo)((()=>e),n.flat())}function d(e){return n=>{let{children:t}=n;return o.createElement(o.Fragment,null,e.reduceRight(((e,n)=>o.createElement(n,null,e)),t))}}},86491:(e,n,t)=>{"use strict";function o(e,n){return void 0!==e&&void 0!==n&&new RegExp(e,"gi").test(n)}t.d(n,{G:()=>o})},74378:(e,n,t)=>{"use strict";t.d(n,{Dt:()=>a,ys:()=>i});var o=t(37953),r=t(47862),s=t(77815);function i(e,n){const t=e=>{var n;return null==(n=!e||e.endsWith("/")?e:e+"/")?void 0:n.toLowerCase()};return t(e)===t(n)}function a(){const{baseUrl:e}=(0,s.A)().siteConfig;return(0,o.useMemo)((()=>function(e){let{baseUrl:n,routes:t}=e;function o(e){return e.path===n&&!0===e.exact}function r(e){return e.path===n&&!e.exact}return function e(n){if(0===n.length)return;return n.find(o)||e(n.filter(r).flatMap((e=>{var n;return null!=(n=e.routes)?n:[]})))}(t)}({routes:r.A,baseUrl:e})),[e])}},30727:(e,n,t)=>{"use strict";t.d(n,{Mq:()=>l,Tv:()=>c,a_:()=>p,gk:()=>g});var o=t(37953),r=t(59536),s=t(82182),i=t(30893);const a=o.createContext(void 0);function c(e){let{children:n}=e;const t=function(){const e=(0,o.useRef)(!0);return(0,o.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return o.createElement(a.Provider,{value:t},n)}function d(){const e=(0,o.useContext)(a);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const u=()=>r.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function l(e,n){void 0===n&&(n=[]);const{scrollEventsEnabledRef:t}=d(),r=(0,o.useRef)(u()),s=(0,i._q)(e);(0,o.useEffect)((()=>{const e=()=>{if(!t.current)return;const e=u();s(e,r.current),r.current=e},n={passive:!0};return e(),window.addEventListener("scroll",e,n),()=>window.removeEventListener("scroll",e,n)}),[s,t,...n])}function p(){const e=d(),n=function(){const e=(0,o.useRef)({elem:null,top:0}),n=(0,o.useCallback)((n=>{e.current={elem:n,top:n.getBoundingClientRect().top}}),[]),t=(0,o.useCallback)((()=>{const{current:{elem:n,top:t}}=e;if(!n)return{restored:!1};const o=n.getBoundingClientRect().top-t;return o&&window.scrollBy({left:0,top:o}),e.current={elem:null,top:0},{restored:0!==o}}),[]);return(0,o.useMemo)((()=>({save:n,restore:t})),[t,n])}(),t=(0,o.useRef)(void 0),r=(0,o.useCallback)((o=>{n.save(o),e.disableScrollEvents(),t.current=()=>{const{restored:o}=n.restore();if(t.current=void 0,o){const n=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",n)};window.addEventListener("scroll",n)}else e.enableScrollEvents()}}),[e,n]);return(0,o.useLayoutEffect)((()=>{queueMicrotask((()=>null==t.current?void 0:t.current()))})),{blockElementScrollPositionUntilNextRender:r}}function g(){const e=(0,o.useRef)(null),n=(0,s.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:t=>{e.current=n?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(t):function(e){let n=null;const t=document.documentElement.scrollTop>e;return function o(){const r=document.documentElement.scrollTop;(t&&r>e||!t&&rn&&cancelAnimationFrame(n)}(t)},cancelScroll:()=>null==e.current?void 0:e.current()}}},49728:(e,n,t)=>{"use strict";t.d(n,{Cy:()=>i,af:()=>c,tU:()=>a});var o=t(82952),r=t(77815),s=t(17182);const i="default";function a(e,n){return"docs-"+e+"-"+n}function c(){const{i18n:e}=(0,r.A)(),n=(0,o.Gy)(),t=(0,o.gk)(),c=(0,s.XK)();const d=[i,...Object.keys(n).map((function(e){var o;const r=(null==t?void 0:t.activePlugin.pluginId)===e?t.activeVersion:void 0,s=c[e],i=n[e].versions.find((e=>e.isLast));return a(e,(null!=(o=null!=r?r:s)?o:i).name)}))];return{locale:e.currentLocale,tags:d}}},15323:(e,n,t)=>{"use strict";t.d(n,{Dv:()=>l,Wf:()=>u});var o=t(37953),r=t(86872);const s="localStorage";function i(e){let{key:n,oldValue:t,newValue:o,storage:r}=e;if(t===o)return;const s=document.createEvent("StorageEvent");s.initStorageEvent("storage",!1,!1,n,t,o,window.location.href,r),window.dispatchEvent(s)}function a(e){if(void 0===e&&(e=s),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(t){return n=t,c||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",n),c=!0),null}var n}let c=!1;const d={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,n){if("undefined"==typeof window)return function(e){function n(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:n,set:n,del:n,listen:n}}(e);const t=a(null==n?void 0:n.persistence);return null===t?d:{get:()=>{try{return t.getItem(e)}catch(n){return console.error("Docusaurus storage error, can't get key="+e,n),null}},set:n=>{try{const o=t.getItem(e);t.setItem(e,n),i({key:e,oldValue:o,newValue:n,storage:t})}catch(o){console.error("Docusaurus storage error, can't set "+e+"="+n,o)}},del:()=>{try{const n=t.getItem(e);t.removeItem(e),i({key:e,oldValue:n,newValue:null,storage:t})}catch(n){console.error("Docusaurus storage error, can't delete key="+e,n)}},listen:n=>{try{const o=o=>{o.storageArea===t&&o.key===e&&n(o)};return window.addEventListener("storage",o),()=>window.removeEventListener("storage",o)}catch(o){return console.error("Docusaurus storage error, can't listen for changes of key="+e,o),()=>{}}}}}function l(e,n){const t=(0,o.useRef)((()=>null===e?d:u(e,n))).current(),s=(0,o.useCallback)((e=>"undefined"==typeof window?()=>{}:t.listen(e)),[t]);return[(0,r.useSyncExternalStore)(s,(()=>"undefined"==typeof window?null:t.get()),(()=>null)),t]}},70892:(e,n,t)=>{"use strict";t.d(n,{o:()=>s});var o=t(77815),r=t(45926);function s(){const{siteConfig:{baseUrl:e,url:n},i18n:{defaultLocale:t,currentLocale:s}}=(0,o.A)(),{pathname:i}=(0,r.zy)(),a=s===t?e:e.replace("/"+s+"/","/"),c=i.replace(e,"");return{createUrl:function(e){let{locale:o,fullyQualified:r}=e;return""+(r?n:"")+function(e){return e===t?""+a:""+a+e+"/"}(o)+c}}}},14913:(e,n,t)=>{"use strict";t.d(n,{$:()=>i});var o=t(37953),r=t(45926),s=t(30893);function i(e){const n=(0,r.zy)(),t=(0,s.ZC)(n),i=(0,s._q)(e);(0,o.useEffect)((()=>{t&&n!==t&&i({location:n,previousLocation:t})}),[i,n,t])}},5615:(e,n,t)=>{"use strict";t.d(n,{p:()=>r});var o=t(77815);function r(){return(0,o.A)().siteConfig.themeConfig}},49273:(e,n,t)=>{"use strict";t.d(n,{c:()=>r});var o=t(77815);function r(){const{siteConfig:{themeConfig:e}}=(0,o.A)();return e}},93901:(e,n,t)=>{"use strict";t.d(n,{C:()=>a});var o=t(37953),r=t(86491),s=t(90900),i=t(49273);function a(){const{withBaseUrl:e}=(0,s.h)(),{algolia:{externalUrlRegex:n,replaceSearchResultPathname:t}}=(0,i.c)();return(0,o.useCallback)((o=>{const s=new URL(o);if((0,r.G)(n,s.href))return o;const i=""+(s.pathname+s.hash);return e(function(e,n){return n?e.replaceAll(new RegExp(n.from,"g"),n.to):e}(i,t))}),[e,n,t])}},12068:(e,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,n){const{trailingSlash:t,baseUrl:o}=n;if(e.startsWith("#"))return e;if(void 0===t)return e;const[r]=e.split(/[#?]/),s="/"===r||r===o?r:(i=r,t?function(e){return e.endsWith("/")?e:e+"/"}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(r,s)}},73170:(e,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.getErrorCausalChain=void 0,n.getErrorCausalChain=function e(n){return n.cause?[n,...e(n.cause)]:[n]}},16097:function(e,n,t){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.getErrorCausalChain=n.applyTrailingSlash=n.blogPostContainerID=void 0,n.blogPostContainerID="__blog-post-container";var r=t(12068);Object.defineProperty(n,"applyTrailingSlash",{enumerable:!0,get:function(){return o(r).default}});var s=t(73170);Object.defineProperty(n,"getErrorCausalChain",{enumerable:!0,get:function(){return s.getErrorCausalChain}})},68835:(e,n,t)=>{"use strict";function o(e){var n,t,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(n=0;nr});const r=function(){for(var e,n,t=0,r="";t{"use strict";t.d(n,{zR:()=>x,TM:()=>L,yJ:()=>_,sC:()=>N,AO:()=>m,Fu:()=>f});var o=t(72994);function r(e){return"/"===e.charAt(0)}function s(e,n){for(var t=n,o=t+1,r=e.length;o=0;p--){var g=i[p];"."===g?s(i,p):".."===g?(s(i,p),l++):l&&(s(i,p),l--)}if(!d)for(;l--;l)i.unshift("..");!d||""===i[0]||i[0]&&r(i[0])||i.unshift("");var m=i.join("/");return t&&"/"!==m.substr(-1)&&(m+="/"),m};function a(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const c=function e(n,t){if(n===t)return!0;if(null==n||null==t)return!1;if(Array.isArray(n))return Array.isArray(t)&&n.length===t.length&&n.every((function(n,o){return e(n,t[o])}));if("object"==typeof n||"object"==typeof t){var o=a(n),r=a(t);return o!==n||r!==t?e(o,r):Object.keys(Object.assign({},n,t)).every((function(o){return e(n[o],t[o])}))}return!1};var d=t(44599);function u(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function p(e,n){return function(e,n){return 0===e.toLowerCase().indexOf(n.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(n.length))}(e,n)?e.substr(n.length):e}function g(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var n=e.pathname,t=e.search,o=e.hash,r=n||"/";return t&&"?"!==t&&(r+="?"===t.charAt(0)?t:"?"+t),o&&"#"!==o&&(r+="#"===o.charAt(0)?o:"#"+o),r}function _(e,n,t,r){var s;"string"==typeof e?(s=function(e){var n=e||"/",t="",o="",r=n.indexOf("#");-1!==r&&(o=n.substr(r),n=n.substr(0,r));var s=n.indexOf("?");return-1!==s&&(t=n.substr(s),n=n.substr(0,s)),{pathname:n,search:"?"===t?"":t,hash:"#"===o?"":o}}(e),s.state=n):(void 0===(s=(0,o.A)({},e)).pathname&&(s.pathname=""),s.search?"?"!==s.search.charAt(0)&&(s.search="?"+s.search):s.search="",s.hash?"#"!==s.hash.charAt(0)&&(s.hash="#"+s.hash):s.hash="",void 0!==n&&void 0===s.state&&(s.state=n));try{s.pathname=decodeURI(s.pathname)}catch(a){throw a instanceof URIError?new URIError('Pathname "'+s.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):a}return t&&(s.key=t),r?s.pathname?"/"!==s.pathname.charAt(0)&&(s.pathname=i(s.pathname,r.pathname)):s.pathname=r.pathname:s.pathname||(s.pathname="/"),s}function f(e,n){return e.pathname===n.pathname&&e.search===n.search&&e.hash===n.hash&&e.key===n.key&&c(e.state,n.state)}function h(){var e=null;var n=[];return{setPrompt:function(n){return e=n,function(){e===n&&(e=null)}},confirmTransitionTo:function(n,t,o,r){if(null!=e){var s="function"==typeof e?e(n,t):e;"string"==typeof s?"function"==typeof o?o(s,r):r(!0):r(!1!==s)}else r(!0)},appendListener:function(e){var t=!0;function o(){t&&e.apply(void 0,arguments)}return n.push(o),function(){t=!1,n=n.filter((function(e){return e!==o}))}},notifyListeners:function(){for(var e=arguments.length,t=new Array(e),o=0;on?t.splice(n,t.length-n,r):t.push(r),l({action:o,location:r,index:n,entries:t})}}))},replace:function(e,n){var o="REPLACE",r=_(e,n,p(),y.location);u.confirmTransitionTo(r,o,t,(function(e){e&&(y.entries[y.index]=r,l({action:o,location:r}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var n=y.index+e;return n>=0&&n{"use strict";var o=t(35959),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},s={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},a={};function c(e){return o.isMemo(e)?i:a[e.$$typeof]||r}a[o.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},a[o.Memo]=i;var d=Object.defineProperty,u=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,g=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(n,t,o){if("string"!=typeof t){if(m){var r=g(t);r&&r!==m&&e(n,r,o)}var i=u(t);l&&(i=i.concat(l(t)));for(var a=c(n),_=c(t),f=0;f{"use strict";e.exports=function(e,n,t,o,r,s,i,a){if(!e){var c;if(void 0===n)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[t,o,r,s,i,a],u=0;(c=new Error(n.replace(/%s/g,(function(){return d[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},5526:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},64215:(e,n,t)=>{"use strict";t.r(n)},63279:(e,n,t)=>{"use strict";t.r(n)},58744:function(e,n,t){var o,r;o=function(){var e,n,t={version:"0.2.0"},o=t.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function r(e,n,t){return et?t:e}function s(e){return 100*(-1+e)}function i(e,n,t){var r;return(r="translate3d"===o.positionUsing?{transform:"translate3d("+s(e)+"%,0,0)"}:"translate"===o.positionUsing?{transform:"translate("+s(e)+"%,0)"}:{"margin-left":s(e)+"%"}).transition="all "+n+"ms "+t,r}t.configure=function(e){var n,t;for(n in e)void 0!==(t=e[n])&&e.hasOwnProperty(n)&&(o[n]=t);return this},t.status=null,t.set=function(e){var n=t.isStarted();e=r(e,o.minimum,1),t.status=1===e?null:e;var s=t.render(!n),d=s.querySelector(o.barSelector),u=o.speed,l=o.easing;return s.offsetWidth,a((function(n){""===o.positionUsing&&(o.positionUsing=t.getPositioningCSS()),c(d,i(e,u,l)),1===e?(c(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){c(s,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){t.remove(),n()}),u)}),u)):setTimeout(n,u)})),this},t.isStarted=function(){return"number"==typeof t.status},t.start=function(){t.status||t.set(0);var e=function(){setTimeout((function(){t.status&&(t.trickle(),e())}),o.trickleSpeed)};return o.trickle&&e(),this},t.done=function(e){return e||t.status?t.inc(.3+.5*Math.random()).set(1):this},t.inc=function(e){var n=t.status;return n?("number"!=typeof e&&(e=(1-n)*r(Math.random()*n,.1,.95)),n=r(n+e,0,.994),t.set(n)):t.start()},t.trickle=function(){return t.inc(Math.random()*o.trickleRate)},e=0,n=0,t.promise=function(o){return o&&"resolved"!==o.state()?(0===n&&t.start(),e++,n++,o.always((function(){0==--n?(e=0,t.done()):t.set((e-n)/e)})),this):this},t.render=function(e){if(t.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var n=document.createElement("div");n.id="nprogress",n.innerHTML=o.template;var r,i=n.querySelector(o.barSelector),a=e?"-100":s(t.status||0),d=document.querySelector(o.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+a+"%,0,0)"}),o.showSpinner||(r=n.querySelector(o.spinnerSelector))&&g(r),d!=document.body&&u(d,"nprogress-custom-parent"),d.appendChild(n),n},t.remove=function(){l(document.documentElement,"nprogress-busy"),l(document.querySelector(o.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&g(e)},t.isRendered=function(){return!!document.getElementById("nprogress")},t.getPositioningCSS=function(){var e=document.body.style,n="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return n+"Perspective"in e?"translate3d":n+"Transform"in e?"translate":"margin"};var a=function(){var e=[];function n(){var t=e.shift();t&&t(n)}return function(t){e.push(t),1==e.length&&n()}}(),c=function(){var e=["Webkit","O","Moz","ms"],n={};function t(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,n){return n.toUpperCase()}))}function o(n){var t=document.body.style;if(n in t)return n;for(var o,r=e.length,s=n.charAt(0).toUpperCase()+n.slice(1);r--;)if((o=e[r]+s)in t)return o;return n}function r(e){return e=t(e),n[e]||(n[e]=o(e))}function s(e,n,t){n=r(n),e.style[n]=t}return function(e,n){var t,o,r=arguments;if(2==r.length)for(t in n)void 0!==(o=n[t])&&n.hasOwnProperty(t)&&s(e,t,o);else s(e,r[1],r[2])}}();function d(e,n){return("string"==typeof e?e:p(e)).indexOf(" "+n+" ")>=0}function u(e,n){var t=p(e),o=t+n;d(t,n)||(e.className=o.substring(1))}function l(e,n){var t,o=p(e);d(e,n)&&(t=o.replace(" "+n+" "," "),e.className=t.substring(1,t.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function g(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return t},void 0===(r="function"==typeof o?o.call(n,t,n,e):o)||(e.exports=r)},84059:e=>{"use strict";var n=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},t=0;t<10;t++)n["_"+String.fromCharCode(t)]=t;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n[e]})).join(""))return!1;var o={};return"abcdefghijklmnopqrst".split("").forEach((function(e){o[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},o)).join("")}catch(r){return!1}}()?Object.assign:function(e,r){for(var s,i,a=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),c=1;c{var o=t(5526);e.exports=g,e.exports.parse=s,e.exports.compile=function(e,n){return a(s(e,n),n)},e.exports.tokensToFunction=a,e.exports.tokensToRegExp=p;var r=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function s(e,n){for(var t,o=[],s=0,i=0,a="",u=n&&n.delimiter||"/";null!=(t=r.exec(e));){var l=t[0],p=t[1],g=t.index;if(a+=e.slice(i,g),i=g+l.length,p)a+=p[1];else{var m=e[i],_=t[2],f=t[3],h=t[4],b=t[5],v=t[6],y=t[7];a&&(o.push(a),a="");var w=null!=_&&null!=m&&m!==_,k="+"===v||"*"===v,x="?"===v||"*"===v,E=t[2]||u,S=h||b;o.push({name:f||s++,prefix:_||"",delimiter:E,optional:x,repeat:k,partial:w,asterisk:!!y,pattern:S?d(S):y?".*":"[^"+c(E)+"]+?"})}}return i{"use strict";t.d(n,{A:()=>s});var o=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,t={},o={util:{encode:function e(n){return n instanceof r?new r(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);x+=k.value.length,k=k.next){var E=k.value;if(n.length>e.length)return;if(!(E instanceof r)){var S,A=1;if(b){if(!(S=s(w,x,e,h))||S.index>=e.length)break;var C=S.index,T=S.index+S[0].length,L=x;for(L+=k.value.length;C>=L;)L+=(k=k.next).value.length;if(x=L-=k.value.length,k.value instanceof r)continue;for(var R=k;R!==n.tail&&(Ll.reach&&(l.reach=I);var D=k.prev;if(P&&(D=c(n,D,P),x+=P.length),d(n,D,A),k=c(n,D,new r(p,f?o.tokenize(N,f):N,v,N)),O&&c(n,k,O),A>1){var q={cause:p+","+m,reach:I};i(e,n,t,k.prev,x,q),l&&q.reach>l.reach&&(l.reach=q.reach)}}}}}}function a(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function c(e,n,t){var o=n.next,r={value:t,prev:n,next:o};return n.next=r,o.prev=r,e.length++,r}function d(e,n,t){for(var o=n.next,r=0;r"+s.content+""},o}(),r=o;o.default=o,r.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},r.languages.markup.tag.inside["attr-value"].inside.entity=r.languages.markup.entity,r.languages.markup.doctype.inside["internal-subset"].inside=r.languages.markup,r.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(r.languages.markup.tag,"addInlined",{value:function(e,n){var t={};t["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:r.languages[n]},t.cdata=/^$/i;var o={"included-cdata":{pattern://i,inside:t}};o["language-"+n]={pattern:/[\s\S]+/,inside:r.languages[n]};var s={};s[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:o},r.languages.insertBefore("markup","cdata",s)}}),Object.defineProperty(r.languages.markup.tag,"addAttribute",{value:function(e,n){r.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:r.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),r.languages.html=r.languages.markup,r.languages.mathml=r.languages.markup,r.languages.svg=r.languages.markup,r.languages.xml=r.languages.extend("markup",{}),r.languages.ssml=r.languages.xml,r.languages.atom=r.languages.xml,r.languages.rss=r.languages.xml,function(e){var n="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",t={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},o={bash:t,environment:{pattern:RegExp("\\$"+n),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+n),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+n),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:o},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:t}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:o},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:o.entity}}],environment:{pattern:RegExp("\\$?"+n),alias:"constant"},variable:o.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},t.inside=e.languages.bash;for(var r=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],s=o.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},r.languages.c=r.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),r.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),r.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},r.languages.c.string],char:r.languages.c.char,comment:r.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:r.languages.c}}}}),r.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete r.languages.c.boolean,function(e){var n=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,t=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return n.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return n.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:n,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return t}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(r),function(e){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(r),function(e){var n,t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:n={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=n,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var o={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},r={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:o,number:r,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:o,number:r})}(r),r.languages.javascript=r.languages.extend("clike",{"class-name":[r.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),r.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,r.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:r.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:r.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:r.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:r.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:r.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),r.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:r.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),r.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),r.languages.markup&&(r.languages.markup.tag.addInlined("script","javascript"),r.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),r.languages.js=r.languages.javascript,function(e){var n=/#(?!\{).+/,t={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:n,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:t}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:n,interpolation:t}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:t}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(r),function(e){var n=/[*&][^\s[\]{},]+/,t=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,o="(?:"+t.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+t.source+")?)",r=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),s=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,n){n=(n||"").replace(/m/g,"")+"m";var t=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return o})).replace(/<>/g,(function(){return e}));return RegExp(t,n)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return o}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return o})).replace(/<>/g,(function(){return"(?:"+r+"|"+s+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(s),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:t,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(r),function(e){var n=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function t(e){return e=e.replace(//g,(function(){return n})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var o=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,r=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return o})),s=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+r+s+"(?:"+r+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+r+s+")(?:"+r+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(o),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+r+")"+s+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+r+"$"),inside:{"table-header":{pattern:RegExp(o),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:t(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:t(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:t(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:t(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(n){["url","bold","italic","strike","code-snippet"].forEach((function(t){n!==t&&(e.languages.markdown[n].inside.content.inside[t]=e.languages.markdown[t])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(n){if(n&&"string"!=typeof n)for(var t=0,o=n.length;t",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(r),r.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:r.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},r.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var n=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),t=0;t0)){var a=p(/^\{$/,/^\}$/);if(-1===a)continue;for(var c=t;c=0&&g(d,"variable-input")}}}}function u(e){return n[t+e]}function l(e,n){n=n||0;for(var t=0;t?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var n=e.languages.javascript["template-string"],t=n.pattern.source,o=n.inside.interpolation,r=o.inside["interpolation-punctuation"],s=o.pattern.source;function i(n,o){if(e.languages[n])return{pattern:RegExp("((?:"+o+")\\s*)"+t),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:n}}}}function a(e,n){return"___"+n.toUpperCase()+"_"+e+"___"}function c(n,t,o){var r={code:n,grammar:t,language:o};return e.hooks.run("before-tokenize",r),r.tokens=e.tokenize(r.code,r.grammar),e.hooks.run("after-tokenize",r),r.tokens}function d(n){var t={};t["interpolation-punctuation"]=r;var s=e.tokenize(n,t);if(3===s.length){var i=[1,1];i.push.apply(i,c(s[1],e.languages.javascript,"javascript")),s.splice.apply(s,i)}return new e.Token("interpolation",s,o.alias,n)}function u(n,t,o){var r=e.tokenize(n,{interpolation:{pattern:RegExp(s),lookbehind:!0}}),i=0,u={},l=c(r.map((function(e){if("string"==typeof e)return e;for(var t,r=e.content;-1!==n.indexOf(t=a(i++,o)););return u[t]=r,t})).join(""),t,o),p=Object.keys(u);return i=0,function e(n){for(var t=0;t=p.length)return;var o=n[t];if("string"==typeof o||"string"==typeof o.content){var r=p[i],s="string"==typeof o?o:o.content,a=s.indexOf(r);if(-1!==a){++i;var c=s.substring(0,a),l=d(u[r]),g=s.substring(a+r.length),m=[];if(c&&m.push(c),m.push(l),g){var _=[g];e(_),m.push.apply(m,_)}"string"==typeof o?(n.splice.apply(n,[t,1].concat(m)),t+=m.length-1):o.content=m}}else{var f=o.content;Array.isArray(f)?e(f):e([f])}}}(l),new e.Token(o,l,"language-"+o,n)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),n].filter(Boolean);var l={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(n){n.language in l&&function n(t){for(var o=0,r=t.length;o]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var n=e.languages.extend("typescript",{});delete n["class-name"],e.languages.typescript["class-name"].inside=n,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:n}}}}),e.languages.ts=e.languages.typescript}(r),function(e){function n(e,n){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),n)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:n(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:n(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:n(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var t=["function","function-variable","method","method-variable","property-access"],o=0;o*\.{3}(?:[^{}]|)*\})/.source;function s(e,n){return e=e.replace(//g,(function(){return t})).replace(//g,(function(){return o})).replace(//g,(function(){return r})),RegExp(e,n)}r=s(r).source,e.languages.jsx=e.languages.extend("markup",n),e.languages.jsx.tag.pattern=s(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=n.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:s(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:s(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},a=function(n){for(var t=[],o=0;o0&&t[t.length-1].tagName===i(r.content[0].content[1])&&t.pop():"/>"===r.content[r.content.length-1].content||t.push({tagName:i(r.content[0].content[1]),openedBraces:0}):t.length>0&&"punctuation"===r.type&&"{"===r.content?t[t.length-1].openedBraces++:t.length>0&&t[t.length-1].openedBraces>0&&"punctuation"===r.type&&"}"===r.content?t[t.length-1].openedBraces--:s=!0),(s||"string"==typeof r)&&t.length>0&&0===t[t.length-1].openedBraces){var c=i(r);o0&&("string"==typeof n[o-1]||"plain-text"===n[o-1].type)&&(c=i(n[o-1])+c,n.splice(o-1,1),o--),n[o]=new e.Token("plain-text",c,null,c)}r.content&&"string"!=typeof r.content&&a(r.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||a(e.tokens)}))}(r),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var n={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(n).forEach((function(t){var o=n[t],r=[];/^\w+$/.test(t)||r.push(/\w+/.exec(t)[0]),"diff"===t&&r.push("bold"),e.languages.diff[t]={pattern:RegExp("^(?:["+o+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:r,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(t)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:n})}(r),r.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},r.languages.go=r.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),r.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete r.languages.go["class-name"],function(e){function n(e,n){return"___"+e.toUpperCase()+n+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(t,o,r,s){if(t.language===o){var i=t.tokenStack=[];t.code=t.code.replace(r,(function(e){if("function"==typeof s&&!s(e))return e;for(var r,a=i.length;-1!==t.code.indexOf(r=n(o,a));)++a;return i[a]=e,r})),t.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(t,o){if(t.language===o&&t.tokenStack){t.grammar=e.languages[o];var r=0,s=Object.keys(t.tokenStack);!function i(a){for(var c=0;c=s.length);c++){var d=a[c];if("string"==typeof d||d.content&&"string"==typeof d.content){var u=s[r],l=t.tokenStack[u],p="string"==typeof d?d:d.content,g=n(o,u),m=p.indexOf(g);if(m>-1){++r;var _=p.substring(0,m),f=new e.Token(o,e.tokenize(l,t.grammar),"language-"+o,l),h=p.substring(m+g.length),b=[];_&&b.push.apply(b,i([_])),b.push(f),h&&b.push.apply(b,i([h])),"string"==typeof d?a.splice.apply(a,[c,1].concat(b)):d.content=b}}else d.content&&i(d.content)}return a}(t.tokens)}}}})}(r),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(n){e.languages["markup-templating"].buildPlaceholders(n,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"handlebars")})),e.languages.hbs=e.languages.handlebars}(r),r.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},r.languages.webmanifest=r.languages.json,r.languages.less=r.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),r.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),r.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},r.languages.objectivec=r.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete r.languages.objectivec["class-name"],r.languages.objc=r.languages.objectivec,r.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},r.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},r.languages.python["string-interpolation"].inside.interpolation.inside.rest=r.languages.python,r.languages.py=r.languages.python,r.languages.reason=r.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),r.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete r.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var n=/\$[-\w]+|#\{\$[-\w]+\}/,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:n,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:n,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(r),r.languages.scss=r.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),r.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),r.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),r.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),r.languages.scss.atrule.inside.rest=r.languages.scss,function(e){var n={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},t={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},o={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:n,number:t,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:n,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:t,punctuation:/[{}()\[\];:,]/};o.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:o}},o.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:o}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:o}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:o}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:o}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:o.interpolation}},rest:o}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:o.interpolation,comment:o.comment,punctuation:/[{},]/}},func:o.func,string:o.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:o.interpolation,punctuation:/[{}()\[\];:.]/}}(r),function(e){var n=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",n),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var t=e.languages.tsx.tag;t.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(r),r.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const s=r},53408:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:"shell",aliasTitles:{shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (Scss)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},3895:(e,n,t)=>{const o=t(53408),r=t(27045),s=new Set;function i(e){void 0===e?e=Object.keys(o.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const n=[...s,...Object.keys(Prism.languages)];r(o,e,n).load((e=>{if(!(e in o.languages))return void(i.silent||console.warn("Language does not exist: "+e));const n="./prism-"+e;delete t.c[t(42584).resolve(n)],delete Prism.languages[e],t(42584)(n),s.add(e)}))}i.silent=!1,e.exports=i},42584:(e,n,t)=>{var o={"./":3895};function r(e){var n=s(e);return t(n)}function s(e){if(!t.o(o,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=s,e.exports=r,r.id=42584},27045:e=>{"use strict";var n=function(){var e=function(){};function n(e,n){Array.isArray(e)?e.forEach(n):null!=e&&n(e,0)}function t(e){for(var n={},t=0,o=e.length;t "));var a={},c=e[o];if(c){function d(n){if(!(n in e))throw new Error(o+" depends on an unknown component "+n);if(!(n in a))for(var i in r(n,s),a[n]=!0,t[n])a[i]=!0}n(c.require,d),n(c.optional,d),n(c.modify,d)}t[o]=a,s.pop()}}return function(e){var n=t[e];return n||(r(e,o),n=t[e]),n}}function r(e){for(var n in e)return!0;return!1}return function(s,i,a){var c=function(e){var n={};for(var t in e){var o=e[t];for(var r in o)if("meta"!=r){var s=o[r];n[r]="string"==typeof s?{title:s}:s}}return n}(s),d=function(e){var t;return function(o){if(o in e)return o;if(!t)for(var r in t={},e){var s=e[r];n(s&&s.alias,(function(n){if(n in t)throw new Error(n+" cannot be alias for both "+r+" and "+t[n]);if(n in e)throw new Error(n+" cannot be alias of "+r+" because it is a component.");t[n]=r}))}return t[o]||o}}(c);i=i.map(d),a=(a||[]).map(d);var u=t(i),l=t(a);i.forEach((function e(t){var o=c[t];n(o&&o.require,(function(n){n in l||(u[n]=!0,e(n))}))}));for(var p,g=o(c),m=u;r(m);){for(var _ in p={},m){var f=c[_];n(f&&f.modify,(function(e){e in l&&(p[e]=!0)}))}for(var h in l)if(!(h in u))for(var b in g(h))if(b in u){p[h]=!0;break}for(var v in m=p)u[v]=!0}var y={getIds:function(){var e=[];return y.load((function(n){e.push(n)})),e},load:function(n,t){return function(n,t,o,r){var s=r?r.series:void 0,i=r?r.parallel:e,a={},c={};function d(e){if(e in a)return a[e];c[e]=!0;var r,u=[];for(var l in n(e))l in t&&u.push(l);if(0===u.length)r=o(e);else{var p=i(u.map((function(e){var n=d(e);return delete c[e],n})));s?r=s(p,(function(){return o(e)})):o(e)}return a[e]=r}for(var u in t)d(u);var l=[];for(var p in c)l.push(a[p]);return i(l)}(g,u,n,t)}};return y}}();e.exports=n},16186:(e,n,t)=>{"use strict";var o=t(62985);function r(){}function s(){}s.resetWarningCache=r,e.exports=function(){function e(e,n,t,r,s,i){if(i!==o){var a=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw a.name="Invariant Violation",a}}function n(){return e}e.isRequired=e;var t={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:n,element:e,elementType:e,instanceOf:n,node:e,objectOf:n,oneOf:n,oneOfType:n,shape:n,exact:n,checkPropTypes:s,resetWarningCache:r};return t.PropTypes=t,t}},2736:(e,n,t)=>{e.exports=t(16186)()},62985:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},26647:(e,n,t)=>{"use strict";var o=t(37953),r=t(84059),s=t(76591);function i(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t