You are viewing a plain text version of this content. The canonical link for it is here.
Posted to custos@airavata.apache.org by "ganning127 (via GitHub)" <gi...@apache.org> on 2024/05/23 15:40:40 UTC

[PR] first working version [airavata]

ganning127 opened a new pull request, #435:
URL: https://github.com/apache/airavata/pull/435

   (no comment)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: custos-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "ganning127 (via GitHub)" <gi...@apache.org>.
ganning127 commented on code in PR #435:
URL: https://github.com/apache/airavata/pull/435#discussion_r1727458646


##########
airavata-local-agent/package.json:
##########
@@ -0,0 +1,52 @@
+{

Review Comment:
   verified



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "DImuthuUpe (via GitHub)" <gi...@apache.org>.
DImuthuUpe commented on PR #435:
URL: https://github.com/apache/airavata/pull/435#issuecomment-2305996386

   Great. Thanks @ganning127 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "ganning127 (via GitHub)" <gi...@apache.org>.
ganning127 commented on code in PR #435:
URL: https://github.com/apache/airavata/pull/435#discussion_r1727340568


##########
airavata-local-agent/renderer/components/JupyterLab.jsx:
##########
@@ -0,0 +1,304 @@
+import React, { Component } from "react";
+import { Alert, Spinner, Text } from "@chakra-ui/react";
+
+const HOSTNAME = "https://api2.cybershuttle.org/proxy";
+export default class JupyterLab extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      rendering: false,
+      msg: "",
+      windowClosed: false,
+      serverPort: null
+    };
+    this.associatedId = `JN_${this.props.experimentId}`;
+    this.interval = null;
+    this.interval2 = null;
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    console.log("state: ", this.state, nextState);
+    console.log("props: ", this.props, nextProps);
+
+    return this.state.rendering !== nextState.rendering || this.state.windowClosed !== nextState.windowClosed || this.state.msg !== nextState.msg;
+
+    // return this.state.rendering !== nextState.rendering || this.state.windowClosed !== nextState.windowClosed || this.state.msg !== nextState.msg;
+    // return false;
+  }
+
+  componentDidMount() {
+    const { reqPort, applicationId, headers } = this.props;
+
+    window.ipc.on("window-has-been-closed", (windowAssociatedId) => {
+      console.log("firing...");
+      if (windowAssociatedId === this.associatedId) {
+        console.log("Matching associated Ids, closing window");
+        this.setState({ windowClosed: true });
+      }
+    });
+
+    if (!reqPort) {
+      this.interval = setInterval(async () => {
+        const resp = await fetch(`https://api.cybershuttle.org/api/v1/application/${applicationId}/connect`, {
+          method: "POST",
+          headers: headers,
+        });
+
+        if (!resp.ok) {
+          console.log("Error fetching the application status");
+          clearInterval(this.interval);
+          return;
+        }
+
+        const data = await resp.json();
+
+        if (data.status === "PENDING") {
+          console.log("Waiting for the application to launch...");
+        } else if (data.status === "COMPLETED") {
+          let serverPortFromData = data.allocatedPorts[0];
+          this.setState({ serverPort: serverPortFromData }, () => {
+            this.tryAndLaunchServer(serverPortFromData);
+          });
+          clearInterval(this.interval);
+        }
+      }, 5000);
+    }
+  }
+
+  componentWillUnmount() {
+    console.log("unmounting component...");
+    clearInterval(this.interval);
+    clearInterval(this.interval2);
+    this.setState({ rendering: false });
+  }
+
+  doneWithGettingData = (port) => {
+    this.setState({ rendering: true });
+    console.log("the associated id is", this.associatedId);
+    window.jn.showWindow(`${HOSTNAME}/${port}/lab?token=1234`, this.associatedId);
+
+    console.log("trying to show the window...");
+    this.setState({ msg: "JupyterLab is ready to use in a new window. Please enter 1234 as the password box, if prompted." });
+
+
+  };
+
+  tryAndLaunchServer = async (port) => {
+    console.log("polling the jupyter server...");
+
+
+    try {
+      console.log("in the first try");
+      const resp = await fetch(`${HOSTNAME}/${port}/lab?token=1234`);
+      if (resp.ok) {
+        this.doneWithGettingData(port);
+      } else {
+        throw new Error("Error fetching the application status");
+      }
+
+    } catch (e) {
+      console.log("in the first catch", e);
+      this.interval2 = setInterval(async () => {
+        try {
+          console.log("in the second try");
+          const resp = await fetch(`${HOSTNAME}/${port}/lab?token=1234`);
+
+          if (resp.ok) {
+            clearInterval(this.interval2);
+            this.doneWithGettingData(port);
+          }
+        } catch (ex) {
+          console.log("in the second catch", ex);
+        }
+      }, 5000);
+    }
+  };
+
+  render() {
+    const { rendering, msg, windowClosed } = this.state;
+
+    if (!rendering) {
+      return (
+        <Alert status='info' rounded='md'>
+          <Spinner mr={2} />
+          <Text>
+            We're currently starting the Jupyter Notebook, this may take a few minutes. Please wait...
+          </Text>
+        </Alert>
+      );
+    }
+
+    if (windowClosed) {
+      return (
+        <Alert status='error' rounded='md'>
+          <Text>
+            Please close this tab, your jupyter session is no longer active.
+          </Text>
+        </Alert>
+      );
+    }
+
+    return (
+      <>
+        {
+          msg && (
+            <Alert status='success' rounded='md'>
+              <Text>
+                {msg}
+              </Text>
+            </Alert>
+          )
+        }
+
+        {/* <iframe src={`${HOSTNAME}/${this.state.serverPort}/lab?token=1234`} width="100%" height="100%"></iframe> */}
+
+
+
+        <h1>Note: If you close this tab, your jupyter session will no longer save any changes.</h1>
+      </>
+    );
+  }
+}
+
+

Review Comment:
   deleted



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "ganning127 (via GitHub)" <gi...@apache.org>.
ganning127 commented on PR #435:
URL: https://github.com/apache/airavata/pull/435#issuecomment-2305170844

   depdencies (from package.json)
       "@ajna/pagination": "^1.4.19", // MIT
       "@chakra-ui/icons": "^2.1.1", // MIT
       "@chakra-ui/react": "^2.8.2", // MIT
       "@emotion/react": "^11.11.4", // MIT
       "@emotion/styled": "^11.11.5", // MIT
       "@novnc/novnc": "^1.3.0", // MIT
       "dayjs": "^1.11.11", // MIT
       "dockerode": "^4.0.2", // Apache-2.0
       "electron-is-dev": "^3.0.1", // MIT
       "electron-log": "^5.1.5", // MIT
       "electron-serve": "^1.3.0", // MIT
       "electron-store": "^8.2.0", // MIT
       "framer-motion": "^11.2.0", // MIT
       "protocol-registry": "^1.4.1", // MIT
       "react-icons": "^5.2.1", // MIT
       "react-loading": "^2.0.3", // MIT
       "react-syntax-highlighter": "^15.5.0", // MIT
       "react-vnc": "^1.0.0", // MIT
       "stream": "0.0.3", // MIT
       "tus-js-client": "^1.6.0", // MIT
       "update-electron-app": "^3.0.0", // MIT
       "usehooks-ts": "^3.1.0" // MIT
   
   
   dev deps
       "@electron/fuses": "^1.8.0", // MIT
       "electron": "^29.3.0", // MIT
       "electron-builder": "^24.13.3", // MIT
       "next": "^13.5.6", // MIT
       "nextron": "^8.15.0", // MIT
       "react": "^18.2.0", // MIT
       "react-dom": "^18.2.0" // MIT
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "DImuthuUpe (via GitHub)" <gi...@apache.org>.
DImuthuUpe commented on code in PR #435:
URL: https://github.com/apache/airavata/pull/435#discussion_r1724384562


##########
airavata-local-agent/electron-builder.yml:
##########
@@ -0,0 +1,12 @@
+appId: com.example.nextron

Review Comment:
   Add Apache licence header for all files



##########
airavata-local-agent/package.json:
##########
@@ -0,0 +1,52 @@
+{

Review Comment:
   Please verify whether all the dependencies are apache licence compatible



##########
airavata-local-agent/renderer/components/ExperimentsList.jsx:
##########
@@ -0,0 +1,142 @@
+import { useState } from "react";
+import {
+  Tr, Tooltip, Box, Td, Text, Badge, HStack, Button, Modal,
+  ModalOverlay,
+  ModalContent,
+  ModalHeader,
+  useDisclosure,
+  ModalBody,
+  ModalCloseButton,
+} from "@chakra-ui/react";
+import ExperimentModal from "./ExperimentModal";
+import { getColorScheme, getResourceFromId } from '../lib/utilityFuncs';
+import dayjs from "dayjs";
+import relativeTime from "dayjs/plugin/relativeTime";
+dayjs.extend(relativeTime);
+
+
+const isValidStatus = (status) => {
+  let invalidStatus = ["CREATED"]; // TODO here
+  return !invalidStatus.includes(status);
+};
+
+const getExperimentApplication = (executionId) => {

Review Comment:
   Add a comment explaining why these values are hardcoded



##########
airavata-local-agent/README.md:
##########
@@ -0,0 +1,16 @@
+# Airavata UI
+

Review Comment:
   Please provide a description of the local agent and what purpose it server. Also, please provide some screenshots



##########
airavata-local-agent/renderer/components/ExperimentsList.jsx:
##########
@@ -0,0 +1,142 @@
+import { useState } from "react";
+import {
+  Tr, Tooltip, Box, Td, Text, Badge, HStack, Button, Modal,
+  ModalOverlay,
+  ModalContent,
+  ModalHeader,
+  useDisclosure,
+  ModalBody,
+  ModalCloseButton,
+} from "@chakra-ui/react";
+import ExperimentModal from "./ExperimentModal";
+import { getColorScheme, getResourceFromId } from '../lib/utilityFuncs';
+import dayjs from "dayjs";
+import relativeTime from "dayjs/plugin/relativeTime";
+dayjs.extend(relativeTime);
+
+
+const isValidStatus = (status) => {
+  let invalidStatus = ["CREATED"]; // TODO here

Review Comment:
   What is the TODO here?



##########
airavata-local-agent/renderer/components/JupyterLab.jsx:
##########
@@ -0,0 +1,304 @@
+import React, { Component } from "react";
+import { Alert, Spinner, Text } from "@chakra-ui/react";
+
+const HOSTNAME = "https://api2.cybershuttle.org/proxy";
+export default class JupyterLab extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      rendering: false,
+      msg: "",
+      windowClosed: false,
+      serverPort: null
+    };
+    this.associatedId = `JN_${this.props.experimentId}`;
+    this.interval = null;
+    this.interval2 = null;
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    console.log("state: ", this.state, nextState);
+    console.log("props: ", this.props, nextProps);
+
+    return this.state.rendering !== nextState.rendering || this.state.windowClosed !== nextState.windowClosed || this.state.msg !== nextState.msg;
+
+    // return this.state.rendering !== nextState.rendering || this.state.windowClosed !== nextState.windowClosed || this.state.msg !== nextState.msg;
+    // return false;
+  }
+
+  componentDidMount() {
+    const { reqPort, applicationId, headers } = this.props;
+
+    window.ipc.on("window-has-been-closed", (windowAssociatedId) => {
+      console.log("firing...");
+      if (windowAssociatedId === this.associatedId) {
+        console.log("Matching associated Ids, closing window");
+        this.setState({ windowClosed: true });
+      }
+    });
+
+    if (!reqPort) {
+      this.interval = setInterval(async () => {
+        const resp = await fetch(`https://api.cybershuttle.org/api/v1/application/${applicationId}/connect`, {
+          method: "POST",
+          headers: headers,
+        });
+
+        if (!resp.ok) {
+          console.log("Error fetching the application status");
+          clearInterval(this.interval);
+          return;
+        }
+
+        const data = await resp.json();
+
+        if (data.status === "PENDING") {
+          console.log("Waiting for the application to launch...");
+        } else if (data.status === "COMPLETED") {
+          let serverPortFromData = data.allocatedPorts[0];
+          this.setState({ serverPort: serverPortFromData }, () => {
+            this.tryAndLaunchServer(serverPortFromData);
+          });
+          clearInterval(this.interval);
+        }
+      }, 5000);
+    }
+  }
+
+  componentWillUnmount() {
+    console.log("unmounting component...");
+    clearInterval(this.interval);
+    clearInterval(this.interval2);
+    this.setState({ rendering: false });
+  }
+
+  doneWithGettingData = (port) => {
+    this.setState({ rendering: true });
+    console.log("the associated id is", this.associatedId);
+    window.jn.showWindow(`${HOSTNAME}/${port}/lab?token=1234`, this.associatedId);
+
+    console.log("trying to show the window...");
+    this.setState({ msg: "JupyterLab is ready to use in a new window. Please enter 1234 as the password box, if prompted." });
+
+
+  };
+
+  tryAndLaunchServer = async (port) => {
+    console.log("polling the jupyter server...");
+
+
+    try {
+      console.log("in the first try");
+      const resp = await fetch(`${HOSTNAME}/${port}/lab?token=1234`);
+      if (resp.ok) {
+        this.doneWithGettingData(port);
+      } else {
+        throw new Error("Error fetching the application status");
+      }
+
+    } catch (e) {
+      console.log("in the first catch", e);
+      this.interval2 = setInterval(async () => {
+        try {
+          console.log("in the second try");
+          const resp = await fetch(`${HOSTNAME}/${port}/lab?token=1234`);
+
+          if (resp.ok) {
+            clearInterval(this.interval2);
+            this.doneWithGettingData(port);
+          }
+        } catch (ex) {
+          console.log("in the second catch", ex);
+        }
+      }, 5000);
+    }
+  };
+
+  render() {
+    const { rendering, msg, windowClosed } = this.state;
+
+    if (!rendering) {
+      return (
+        <Alert status='info' rounded='md'>
+          <Spinner mr={2} />
+          <Text>
+            We're currently starting the Jupyter Notebook, this may take a few minutes. Please wait...
+          </Text>
+        </Alert>
+      );
+    }
+
+    if (windowClosed) {
+      return (
+        <Alert status='error' rounded='md'>
+          <Text>
+            Please close this tab, your jupyter session is no longer active.
+          </Text>
+        </Alert>
+      );
+    }
+
+    return (
+      <>
+        {
+          msg && (
+            <Alert status='success' rounded='md'>
+              <Text>
+                {msg}
+              </Text>
+            </Alert>
+          )
+        }
+
+        {/* <iframe src={`${HOSTNAME}/${this.state.serverPort}/lab?token=1234`} width="100%" height="100%"></iframe> */}
+
+
+
+        <h1>Note: If you close this tab, your jupyter session will no longer save any changes.</h1>
+      </>
+    );
+  }
+}
+
+

Review Comment:
   Do we need following commented code?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Airavata Desktop Client [airavata]

Posted by "DImuthuUpe (via GitHub)" <gi...@apache.org>.
DImuthuUpe merged PR #435:
URL: https://github.com/apache/airavata/pull/435


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: custos-unsubscribe@airavata.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org