From e4d2ca620a20211ccd1ae01c240fe3e21ab8dee3 Mon Sep 17 00:00:00 2001 From: Max Fitton Date: Tue, 18 Aug 2020 11:27:46 -0700 Subject: [PATCH] Revert "[Dashboard] Group by Actor Class (#10147)" (#10180) This reverts commit 71f6f83f1d8fb4816222e8c25cffa74f654631eb. --- python/ray/dashboard/client/package-lock.json | 178 ++++++++---------- python/ray/dashboard/client/package.json | 2 +- python/ray/dashboard/client/src/api.ts | 17 +- .../pages/dashboard/logical-view/Actor.tsx | 36 +++- .../logical-view/ActorClassGroup.tsx | 57 ------ .../logical-view/ActorClassGroups.tsx | 39 ---- .../dashboard/logical-view/LogicalView.tsx | 23 ++- python/ray/dashboard/dashboard.py | 11 +- python/ray/dashboard/node_stats.py | 50 ----- 9 files changed, 143 insertions(+), 270 deletions(-) delete mode 100644 python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroup.tsx delete mode 100644 python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroups.tsx diff --git a/python/ray/dashboard/client/package-lock.json b/python/ray/dashboard/client/package-lock.json index bd8ea06dd..68d5dab3c 100644 --- a/python/ray/dashboard/client/package-lock.json +++ b/python/ray/dashboard/client/package-lock.json @@ -1647,22 +1647,22 @@ } }, "@material-ui/core": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz", - "integrity": "sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g==", + "version": "4.9.7", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.9.7.tgz", + "integrity": "sha512-RTRibZgq572GHEskMAG4sP+bt3P3XyIkv3pOTR8grZAW2rSUd6JoGZLRM4S2HkuO7wS7cAU5SpU2s1EsmTgWog==", "requires": { "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.10.0", - "@material-ui/system": "^4.9.14", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.10.2", + "@material-ui/styles": "^4.9.6", + "@material-ui/system": "^4.9.6", + "@material-ui/types": "^5.0.0", + "@material-ui/utils": "^4.9.6", "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.4", + "clsx": "^1.0.2", "hoist-non-react-statics": "^3.3.2", - "popper.js": "1.16.1-lts", + "popper.js": "^1.14.1", "prop-types": "^15.7.2", "react-is": "^16.8.0", - "react-transition-group": "^4.4.0" + "react-transition-group": "^4.3.0" } }, "@material-ui/icons": { @@ -1674,15 +1674,15 @@ } }, "@material-ui/styles": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz", - "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.6.tgz", + "integrity": "sha512-ijgwStEkw1OZ6gCz18hkjycpr/3lKs1hYPi88O/AUn4vMuuGEGAIrqKVFq/lADmZUNF3DOFIk8LDkp7zmjPxtA==", "requires": { "@babel/runtime": "^7.4.4", "@emotion/hash": "^0.8.0", - "@material-ui/types": "^5.1.0", + "@material-ui/types": "^5.0.0", "@material-ui/utils": "^4.9.6", - "clsx": "^1.0.4", + "clsx": "^1.0.2", "csstype": "^2.5.2", "hoist-non-react-statics": "^3.3.2", "jss": "^10.0.3", @@ -1697,25 +1697,24 @@ } }, "@material-ui/system": { - "version": "4.9.14", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz", - "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.6.tgz", + "integrity": "sha512-QtfoAePyqXoZ2HUVSwGb1Ro0kucMCvVjbI0CdYIR21t0Opgfm1Oer6ni9P5lfeXA39xSt0wCierw37j+YES48Q==", "requires": { "@babel/runtime": "^7.4.4", "@material-ui/utils": "^4.9.6", - "csstype": "^2.5.2", "prop-types": "^15.7.2" } }, "@material-ui/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.0.0.tgz", + "integrity": "sha512-UeH2BuKkwDndtMSS0qgx1kCzSMw+ydtj0xx/XbFtxNSTlXydKwzs5gVW5ZKsFlAkwoOOQ9TIsyoCC8hq18tOwg==" }, "@material-ui/utils": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz", - "integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.9.6.tgz", + "integrity": "sha512-gqlBn0JPPTUZeAktn1rgMcy9Iczrr74ecx31tyZLVGdBGGzsxzM6PP6zeS7FuoLS6vG4hoZP7hWnOoHtkR0Kvw==", "requires": { "@babel/runtime": "^7.4.4", "prop-types": "^15.7.2", @@ -2046,9 +2045,9 @@ } }, "@types/react-transition-group": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", - "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.4.tgz", + "integrity": "sha512-8DMUaDqh0S70TjkqU0DxOu80tFUiiaS9rxkWip/nb7gtvAsbqOXm02UCmR8zdcjWujgeYPiPNTVpVpKzUDotwA==", "requires": { "@types/react": "*" } @@ -3748,9 +3747,9 @@ } }, "clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz", + "integrity": "sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==" }, "co": { "version": "4.6.0", @@ -4311,11 +4310,11 @@ } }, "css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.7.tgz", + "integrity": "sha512-VS9Rjt79+p7M0WkPqcAza4Yq1ZHrsHrwf7hPL/bjQB+c1lwmAI+1FXxYTYt818D/50fFVflw0XKleiBN5RITkg==", "requires": { - "@babel/runtime": "^7.8.3", + "@babel/runtime": "^7.6.2", "is-in-browser": "^1.0.2" } }, @@ -4762,19 +4761,12 @@ } }, "dom-helpers": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", - "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz", + "integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==", "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - }, - "dependencies": { - "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" - } + "@babel/runtime": "^7.6.3", + "csstype": "^2.6.7" } }, "dom-serializer": { @@ -6964,9 +6956,9 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, "hyphenate-style-name": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", - "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", + "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" }, "iconv-lite": { "version": "0.4.24", @@ -9865,88 +9857,80 @@ } }, "jss": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.4.0.tgz", - "integrity": "sha512-l7EwdwhsDishXzqTc3lbsbyZ83tlUl5L/Hb16pHCvZliA9lRDdNBZmHzeJHP0sxqD0t1mrMmMR8XroR12JBYzw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz", + "integrity": "sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ==", "requires": { "@babel/runtime": "^7.3.1", - "csstype": "^3.0.2", + "csstype": "^2.6.5", "is-in-browser": "^1.1.3", "tiny-warning": "^1.0.2" - }, - "dependencies": { - "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" - } } }, "jss-plugin-camel-case": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.4.0.tgz", - "integrity": "sha512-9oDjsQ/AgdBbMyRjc06Kl3P8lDCSEts2vYZiPZfGAxbGCegqE4RnMob3mDaBby5H9vL9gWmyyImhLRWqIkRUCw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz", + "integrity": "sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw==", "requires": { "@babel/runtime": "^7.3.1", "hyphenate-style-name": "^1.0.3", - "jss": "10.4.0" + "jss": "10.1.1" } }, "jss-plugin-default-unit": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.4.0.tgz", - "integrity": "sha512-BYJ+Y3RUYiMEgmlcYMLqwbA49DcSWsGgHpVmEEllTC8MK5iJ7++pT9TnKkKBnNZZxTV75ycyFCR5xeLSOzVm4A==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz", + "integrity": "sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.4.0" + "jss": "10.1.1" } }, "jss-plugin-global": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.4.0.tgz", - "integrity": "sha512-b8IHMJUmv29cidt3nI4bUI1+Mo5RZE37kqthaFpmxf5K7r2aAegGliAw4hXvA70ca6ckAoXMUl4SN/zxiRcRag==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz", + "integrity": "sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.4.0" + "jss": "10.1.1" } }, "jss-plugin-nested": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.4.0.tgz", - "integrity": "sha512-cKgpeHIxAP0ygeWh+drpLbrxFiak6zzJ2toVRi/NmHbpkNaLjTLgePmOz5+67ln3qzJiPdXXJB1tbOyYKAP4Pw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz", + "integrity": "sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.4.0", + "jss": "10.1.1", "tiny-warning": "^1.0.2" } }, "jss-plugin-props-sort": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.4.0.tgz", - "integrity": "sha512-j/t0R40/2fp+Nzt6GgHeUFnHVY2kPGF5drUVlgkcwYoHCgtBDOhTTsOfdaQFW6sHWfoQYgnGV4CXdjlPiRrzwA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz", + "integrity": "sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.4.0" + "jss": "10.1.1" } }, "jss-plugin-rule-value-function": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.4.0.tgz", - "integrity": "sha512-w8504Cdfu66+0SJoLkr6GUQlEb8keHg8ymtJXdVHWh0YvFxDG2l/nS93SI5Gfx0fV29dO6yUugXnKzDFJxrdFQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz", + "integrity": "sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw==", "requires": { "@babel/runtime": "^7.3.1", - "jss": "10.4.0", - "tiny-warning": "^1.0.2" + "jss": "10.1.1" } }, "jss-plugin-vendor-prefixer": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.4.0.tgz", - "integrity": "sha512-DpF+/a+GU8hMh/948sBGnKSNfKkoHg2p9aRFUmyoyxgKjOeH9n74Ht3Yt8lOgdZsuWNJbPrvaa3U4PXKwxVpTQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz", + "integrity": "sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw==", "requires": { "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.8", - "jss": "10.4.0" + "css-vendor": "^2.0.7", + "jss": "10.1.1" } }, "jsx-ast-utils": { @@ -11402,9 +11386,9 @@ } }, "popper.js": { - "version": "1.16.1-lts", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", - "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" }, "portfinder": { "version": "1.0.25", @@ -13036,9 +13020,9 @@ } }, "react-transition-group": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz", + "integrity": "sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", diff --git a/python/ray/dashboard/client/package.json b/python/ray/dashboard/client/package.json index 7a9680a9f..fb2af9f1c 100644 --- a/python/ray/dashboard/client/package.json +++ b/python/ray/dashboard/client/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "@material-ui/core": "4.11.0", + "@material-ui/core": "^4.9.7", "@material-ui/icons": "^4.9.1", "@reduxjs/toolkit": "^1.3.1", "@types/classnames": "^2.2.10", diff --git a/python/ray/dashboard/client/src/api.ts b/python/ray/dashboard/client/src/api.ts index 9e8ea97c7..835188911 100644 --- a/python/ray/dashboard/client/src/api.ts +++ b/python/ray/dashboard/client/src/api.ts @@ -155,13 +155,14 @@ export enum ActorState { Dead = 4, } -export type ActorInfo = FullActorInfo | PartialActorInfo; +export type RayletActorInfo = FullActorInfo | PartialActorInfo; export type FullActorInfo = { actorId: string; actorTitle: string; averageTaskExecutionSpeed: number; - children?: ActorInfo[]; + children: RayletInfoResponse["actors"]; + // currentTaskFuncDesc: string[]; ipAddress: string; jobId: string; nodeId: string; @@ -186,8 +187,8 @@ export type FullActorInfo = { }; export type PartialActorInfo = { - actorId?: string; - actorTitle?: string; + actorId: string; + actorTitle: string; requiredResources?: { [key: string]: number }; state: ActorState.Invalid; invalidStateType?: InvalidStateType; @@ -195,12 +196,12 @@ export type PartialActorInfo = { // eslint-disable-next-line export function isFullActorInfo( - actorInfo: ActorInfo, -): actorInfo is FullActorInfo { + rayletInfo: RayletActorInfo, +): rayletInfo is FullActorInfo { // Lint disabled because arrow functions don't play well with type guards. // This function is used to determine what kind of information we have about // a given actor in a response based on its state. - return actorInfo.state !== ActorState.Invalid; + return rayletInfo.state !== ActorState.Invalid; } export type InvalidStateType = "infeasibleActor" | "pendingActor"; @@ -213,7 +214,7 @@ export type RayletInfoResponse = { }; }; actors: { - [actorId: string]: ActorInfo; + [actorId: string]: RayletActorInfo; }; }; diff --git a/python/ray/dashboard/client/src/pages/dashboard/logical-view/Actor.tsx b/python/ray/dashboard/client/src/pages/dashboard/logical-view/Actor.tsx index 3fe6bdcff..f8d9fa539 100644 --- a/python/ray/dashboard/client/src/pages/dashboard/logical-view/Actor.tsx +++ b/python/ray/dashboard/client/src/pages/dashboard/logical-view/Actor.tsx @@ -1,4 +1,5 @@ import { + Collapse, createStyles, Theme, Typography, @@ -7,7 +8,6 @@ import { } from "@material-ui/core"; import React from "react"; import { - ActorInfo, ActorState, checkProfilingStatus, CheckProfilingStatusResponse, @@ -15,9 +15,11 @@ import { isFullActorInfo, launchKillActor, launchProfiling, + RayletActorInfo, } from "../../../api"; import { sum } from "../../../common/util"; import ActorDetailsPane from "./ActorDetailsPane"; +import Actors from "./Actors"; const memoryDebuggingDocLink = "https://docs.ray.io/en/latest/memory-management.html#debugging-using-ray-memory"; @@ -29,7 +31,6 @@ const styles = (theme: Theme) => borderWidth: 1, marginTop: theme.spacing(2), padding: theme.spacing(2), - width: "100%", }, title: { color: theme.palette.text.secondary, @@ -59,10 +60,11 @@ const styles = (theme: Theme) => }); type Props = { - actor: ActorInfo; + actor: RayletActorInfo; }; type State = { + expanded: boolean; profiling: { [profilingId: string]: { startTime: number; @@ -73,9 +75,14 @@ type State = { class Actor extends React.Component, State> { state: State = { + expanded: true, profiling: {}, }; + setExpanded = (expanded: boolean) => () => { + this.setState({ expanded }); + }; + handleProfilingClick = (duration: number) => async () => { const actor = this.props.actor; if (actor.state === ActorState.Alive) { @@ -118,7 +125,7 @@ class Actor extends React.Component, State> { render() { const { classes, actor } = this.props; - const { profiling } = this.state; + const { expanded, profiling } = this.state; const invalidStateType = isFullActorInfo(actor) ? undefined : actor.invalidStateType; @@ -236,7 +243,20 @@ class Actor extends React.Component, State> { {isFullActorInfo(actor) ? ( - Actor {actor.actorId} (Profile for + Actor {actor.actorId}{" "} + {Object.entries(actor.children).length > 0 && ( + + ( + + {expanded ? "Collapse" : "Expand"} + + ) + + )}{" "} + (Profile for {[10, 30, 60].map((duration) => ( {" "} @@ -293,7 +313,7 @@ class Actor extends React.Component, State> { @@ -302,6 +322,10 @@ class Actor extends React.Component, State> { {actorCustomDisplay.length > 0 && ( {actorCustomDisplay} )} + + + + )} diff --git a/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroup.tsx b/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroup.tsx deleted file mode 100644 index 0adf2f8d3..000000000 --- a/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroup.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { - Accordion, - AccordionDetails, - AccordionSummary, - Box, - createStyles, - makeStyles, - Paper, - Typography, -} from "@material-ui/core"; -import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; -import React from "react"; -import { ActorInfo } from "../../../api"; -import Actor from "./Actor"; - -const useActorClassGroupStyles = makeStyles((theme) => - createStyles({ - container: { - margin: theme.spacing(1), - }, - actorEntry: { - width: "100%", - }, - }), -); - -type ActorClassGroupProps = { - title: string; - actors: ActorInfo[]; -}; - -const ActorClassGroup: React.FC = ({ actors, title }) => { - const classes = useActorClassGroupStyles(); - const entries = actors.map((actor, i) => ( - - - - )); - return ( - - - } - aria-controls="panel1a-content" - id="panel1a-header" - > - {title} - - - {entries} - - - - ); -}; - -export default ActorClassGroup; diff --git a/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroups.tsx b/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroups.tsx deleted file mode 100644 index d3ab1f754..000000000 --- a/python/ray/dashboard/client/src/pages/dashboard/logical-view/ActorClassGroups.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from "react"; -import { ActorInfo } from "../../../api"; -import ActorClassGroup from "./ActorClassGroup"; - -type ActorClassGroupsProps = { - actors: ActorInfo[]; -}; - -const extractClassName = (actor: ActorInfo) => { - // Given a python class name like Foo(arg1, arg2) - // this function returns "Foo" - const re = /(.+)\(/; - const matches = actor.actorTitle?.match(re); - if (matches) { - return matches[1]; - } -}; - -const ActorClassGroups: React.FC = ({ actors }) => { - const groups = new Map(); - actors.forEach((actor) => { - const className = extractClassName(actor) ?? "Unknown Class"; - const existingGroup = groups.get(className); - if (existingGroup) { - existingGroup.push(actor); - } else { - groups.set(className, [actor]); - } - }); - - const children = Array.from(groups) - .sort(([title], [title2]) => (title > title2 ? 1 : -1)) - .map(([title, actorGroup]) => ( - - )); - return {children}; -}; - -export default ActorClassGroups; diff --git a/python/ray/dashboard/client/src/pages/dashboard/logical-view/LogicalView.tsx b/python/ray/dashboard/client/src/pages/dashboard/logical-view/LogicalView.tsx index 6c3f70e60..56cef7f06 100644 --- a/python/ray/dashboard/client/src/pages/dashboard/logical-view/LogicalView.tsx +++ b/python/ray/dashboard/client/src/pages/dashboard/logical-view/LogicalView.tsx @@ -7,12 +7,19 @@ import { } from "@material-ui/core"; import React, { useState } from "react"; import { connect } from "react-redux"; -import { ActorInfo, isFullActorInfo, RayletInfoResponse } from "../../../api"; +import { + isFullActorInfo, + RayletActorInfo, + RayletInfoResponse, +} from "../../../api"; import { filterObj } from "../../../common/util"; import { StoreState } from "../../../store"; -import ActorClassGroups from "./ActorClassGroups"; +import Actors from "./Actors"; -const actorMatchesSearch = (actor: ActorInfo, nameFilter: string): boolean => { +const actorMatchesSearch = ( + actor: RayletActorInfo, + nameFilter: string, +): boolean => { // Performs a case insensitive search for the name filter string within the // actor and all of its nested subactors. const actorTitles = getNestedActorTitles(actor); @@ -23,7 +30,7 @@ const actorMatchesSearch = (actor: ActorInfo, nameFilter: string): boolean => { return match !== undefined; }; -const getNestedActorTitles = (actor: ActorInfo): string[] => { +const getNestedActorTitles = (actor: RayletActorInfo): string[] => { const actorTitle = actor.actorTitle; const titles: string[] = actorTitle ? [actorTitle] : []; if (!isFullActorInfo(actor)) { @@ -55,8 +62,10 @@ const LogicalView: React.FC = ({ rayletInfo }) => { } let filteredActors = rayletInfo.actors; if (nameFilter !== "") { - filteredActors = filterObj(filteredActors, ([_, actor]: [any, ActorInfo]) => - actorMatchesSearch(actor, nameFilter), + filteredActors = filterObj( + filteredActors, + ([_, actor]: [any, RayletActorInfo]) => + actorMatchesSearch(actor, nameFilter), ); } @@ -78,7 +87,7 @@ const LogicalView: React.FC = ({ rayletInfo }) => { Search for an actor by name - + )} diff --git a/python/ray/dashboard/dashboard.py b/python/ray/dashboard/dashboard.py index 0ca09ed91..e8d996028 100644 --- a/python/ray/dashboard/dashboard.py +++ b/python/ray/dashboard/dashboard.py @@ -91,8 +91,8 @@ class DashboardController(BaseDashboardController): # (e.g., Actor requires 2 GPUs but there is only 1 gpu available). ready_tasks = sum((data.get("readyTasks", []) for data in D.values()), []) - actors = self.node_stats.get_actors(workers_info_by_node, - infeasible_tasks, ready_tasks) + actor_tree = self.node_stats.get_actor_tree( + workers_info_by_node, infeasible_tasks, ready_tasks) for address, data in D.items(): # process view data @@ -131,14 +131,15 @@ class DashboardController(BaseDashboardController): stats_name, stats_value)) data["extraInfo"] += ", ".join(extra_info_strings) # process actor info - actors_str = json.dumps(actors, indent=2, sort_keys=True) - lines = actors_str.split("\n") + actor_tree_str = json.dumps( + actor_tree, indent=2, sort_keys=True) + lines = actor_tree_str.split("\n") max_line_length = max(map(len, lines)) to_print = [] for line in lines: to_print.append(line + (max_line_length - len(line)) * " ") data["extraInfo"] += "\n" + "\n".join(to_print) - return {"nodes": D, "actors": actors} + return {"nodes": D, "actors": actor_tree} def get_ray_config(self): try: diff --git a/python/ray/dashboard/node_stats.py b/python/ray/dashboard/node_stats.py index 63eb420e8..76f99c67c 100644 --- a/python/ray/dashboard/node_stats.py +++ b/python/ray/dashboard/node_stats.py @@ -9,7 +9,6 @@ import copy import logging import datetime import time -from typing import Dict import re from operator import itemgetter @@ -92,55 +91,6 @@ class NodeStats(threading.Thread): key=itemgetter("boot_time")) return {"clients": node_stats} - # Gets actors in a flat way to allow for grouping by actor type. - def get_actors(self, workers_info_by_node, infeasible_tasks, ready_tasks): - now = time.time() - actors: Dict[str, Dict[str, any]] = {} - # construct flattened actor tree - with self._node_stats_lock: - for addr, actor_id in self._addr_to_actor_id.items(): - actors[actor_id] = copy.deepcopy(self._default_info) - actors[actor_id].update(self._addr_to_extra_info_dict[addr]) - - for node_id, workers_info in workers_info_by_node.items(): - for worker_info in workers_info: - if "coreWorkerStats" in worker_info: - core_worker_stats = worker_info["coreWorkerStats"] - addr = (core_worker_stats["ipAddress"], - str(core_worker_stats["port"])) - if addr in self._addr_to_actor_id: - actor_info = actors[self._addr_to_actor_id[addr]] - format_reply_id(core_worker_stats) - actor_info.update(core_worker_stats) - actor_info["averageTaskExecutionSpeed"] = round( - actor_info["numExecutedTasks"] / - (now - actor_info["timestamp"] / 1000), 2) - actor_info["nodeId"] = node_id - actor_info["pid"] = worker_info["pid"] - - def _update_from_actor_tasks(task, task_spec_type, - invalid_state_type): - actor_id = ray.utils.binary_to_hex( - b64decode(task[task_spec_type]["actorId"])) - task["state"] = -1 - task["invalidStateType"] = invalid_state_type - task["actorTitle"] = task["functionDescriptor"][ - "pythonFunctionDescriptor"]["className"] - format_reply_id(task) - actors[actor_id] = task - - for infeasible_task in infeasible_tasks: - _update_from_actor_tasks(infeasible_task, - "actorCreationTaskSpec", - "infeasibleActor") - - for ready_task in ready_tasks: - _update_from_actor_tasks(ready_task, "actorCreationTaskSpec", - "pendingActor") - - return actors - - # Gets actors in a nested structure showing parent child relationships def get_actor_tree(self, workers_info_by_node, infeasible_tasks, ready_tasks): now = time.time()