Skip to content

Commit

Permalink
feat(ecotag) : add slimfaas UI component to savec the planet
Browse files Browse the repository at this point in the history
  • Loading branch information
guillaume-chervet committed Nov 22, 2024
1 parent 51356dd commit d5a8df9
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Ecotag/ClientApp/public/environment.azure.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"apiUrl": "https://axaguildev-ecotag.azurewebsites.net/api/server/{path}",
"baseUrl": "",
"slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
Expand Down
1 change: 1 addition & 0 deletions src/Ecotag/ClientApp/public/environment.desktop.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"apiUrl": "https://localhost:5001/api/server/{path}",
"baseUrl": "",
"slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
Expand Down
1 change: 1 addition & 0 deletions src/Ecotag/ClientApp/public/environment.dev.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"apiUrl": "https://localhost:5001/api/server/{path}",
"baseUrl": "",
"slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
Expand Down
1 change: 1 addition & 0 deletions src/Ecotag/ClientApp/public/environment.docker.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"apiUrl": "http://localhost:5010/api/server/{path}",
"baseUrl": "",
"slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
Expand Down
1 change: 1 addition & 0 deletions src/Ecotag/ClientApp/public/environment.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"apiUrl": "#{Spa:ApiUrl}#",
"baseUrl": "#{Spa:BaseUrl}#",
"slimfaasBaseUrl": "#{Spa:SlimfaasUrl}#",
"oidc": {
"mode": "#{Spa:Oidc:Mode}#",
"configuration": {
Expand Down
26 changes: 23 additions & 3 deletions src/Ecotag/ClientApp/src/Server/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {CallBackSuccess} from "./shared/Oidc/Callback.component";
import AccessToken from "./AccessToken";
import {useHistory} from "react-router";
import {OidcProvider, OidcSecure} from "@axa-fr/react-oidc";
import PlanetSaver from "./PlanetSaver";

const AppWithOidcProvider = withEnvironment(({environment}) => {

Expand All @@ -41,14 +42,30 @@ const AppWithOidcProvider = withEnvironment(({environment}) => {
>
<TelemetryProvider {...environment.telemetry} >
<OidcSecure>
<Header/>
<Routes/>
<Footer/>
<SlimFaasSwitch />
</OidcSecure>
</TelemetryProvider>
</OidcProvider>
});

const Page = () => (
<>
<Header/>
<Routes/>
<Footer/>
</>
);

const SlimFaasSwitch = ({environment}) => {
const slimfaasBaseUrl= environment.slimfaasBaseUrl
if(slimfaasBaseUrl) {
return <PlanetSaver baseUrl={slimfaasBaseUrl}>
<Page/>
</PlanetSaver>
}
return <Page/>
}


const Authentification = ({environment}) => (
<Router basename={environment.baseUrl}>
Expand All @@ -63,6 +80,9 @@ const Authentification = ({environment}) => (
</Router>
);




const AuthentificationWithEnvironment = withEnvironment(Authentification);

const App = () => (
Expand Down
42 changes: 42 additions & 0 deletions src/Ecotag/ClientApp/src/Server/PlanetSaver.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState, useEffect } from 'react';
import BaseUrlContext from './BaseUrlContext';
import SlimFaasPlanetSaver from "./SlimFaasPlanetSaver.js";

const PlanetSaver = ({ children, baseUrl }) => {
const [isFirstStart, setIsFirstStart] = useState(true); // État pour le premier démarrage

useEffect(() => {
if (!baseUrl) return;

const environmentStarter = new SlimFaasPlanetSaver(baseUrl, {
updateCallback: (data) => {
const allReady = data.every((item) => item.NumberReady >= 1);
if (allReady && isFirstStart) {
setIsFirstStart(false);
}
},
errorCallback: (error) => {
console.error('Erreur détectée :', error);
environmentStarter.updateOverlayMessage('An error occured when starting environment. Please contact an administrator.');
},
overlayMessage: 'Starting the environment...',
});

// Démarrage de la surveillance
environmentStarter.startPolling();

// Nettoyage lors du démontage
return () => environmentStarter.cleanup();
}, [baseUrl, isFirstStart]);

// Pendant le premier démarrage, rien n'est affiché
if (isFirstStart) {
return null;
}

// Une fois le premier démarrage terminé, afficher les enfants
return <>{children}</>;

};

export default PlanetSaver;
190 changes: 190 additions & 0 deletions src/Ecotag/ClientApp/src/Server/SlimFaasPlanetSaver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@

export default class SlimFaasPlanetSaver {
constructor(baseUrl, options = {}) {
this.baseUrl = this.normalizeBaseUrl(baseUrl);
this.updateCallback = options.updateCallback || (() => {});
this.errorCallback = options.errorCallback || (() => {});
this.interval = options.interval || 5000;
this.overlayMessage = options.overlayMessage || 'Starting in progress...';
this.intervalId = null;
this.isDocumentVisible = !document.hidden;
this.overlayElement = null;
this.styleElement = null;
this.isReady = false;
this.handleVisibilityChange = this.handleVisibilityChange.bind(this);
document.addEventListener('visibilitychange', this.handleVisibilityChange);

// Initialise le calque et le style
this.createOverlay();
this.injectStyles();

// Événements personnalisés
this.events = document.createElement('div'); // Utilisé comme bus d'événements
}

// Normalise l'URL de base
normalizeBaseUrl(url) {
let tempUrl = url;
if (tempUrl.endsWith('/')) tempUrl = tempUrl.slice(0, -1);
return tempUrl;
}

// Gestion de la visibilité du document
handleVisibilityChange() {
this.isDocumentVisible = !document.hidden;
if (this.isDocumentVisible) {
this.startPolling();
} else {
this.stopPolling();
}
}

async wakeUpPods(data) {
const wakePromises = data
.filter((item) => item.NumberReady === 0)
.map((item) =>
fetch(`${this.baseUrl}/wake-function/${item.Name}`, {
method: 'POST',
})
);

try {
await Promise.all(wakePromises);
} catch (error) {
console.error("Erreur lors du réveil des pods:", error);
}
}

// Récupère le statut de l'infrastructure
async fetchStatus() {
if (!this.isDocumentVisible) return;

try {
const response = await fetch(`${this.baseUrl}/status-functions`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();

const allReady = data.every((item) => item.NumberReady >= 1);
this.setReadyState(allReady);

this.updateCallback(data);
await this.wakeUpPods(data);
} catch (error) {
const errorMessage = error.message;
this.errorCallback(errorMessage);

// Déclenche un événement "error"
this.triggerEvent('error', { message: errorMessage });

console.error('Erreur lors de la récupération des données :', errorMessage);
}
}

// Définit l'état "ready" et gère le calque
setReadyState(isReady) {
this.isReady = isReady;
if (isReady) {
this.hideOverlay();
} else {
this.showOverlay();
}
}

// Démarre la surveillance (polling)
startPolling() {
if (this.intervalId || !this.baseUrl) return;

this.fetchStatus();

this.intervalId = setInterval(() => {
this.fetchStatus();
}, this.interval);
}

// Arrête la surveillance
stopPolling() {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
}

// Injecte les styles CSS via un élément <style>
injectStyles() {
const cssString = `
.environment-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 1.5rem;
font-weight: bold;
z-index: 1000;
visibility: hidden;
}
.environment-overlay.visible {
visibility: visible;
}
`;

this.styleElement = document.createElement('style');
this.styleElement.textContent = cssString;
document.head.appendChild(this.styleElement);
}

// Crée un calque pour le message d'attente
createOverlay() {
this.overlayElement = document.createElement('div');
this.overlayElement.className = 'environment-overlay';
this.overlayElement.innerText = this.overlayMessage;
document.body.appendChild(this.overlayElement);
}

// Affiche le calque
showOverlay() {
if (this.overlayElement) {
this.overlayElement.classList.add('visible');
}
}

// Cache le calque
hideOverlay() {
if (this.overlayElement) {
this.overlayElement.classList.remove('visible');
}
}

// Met à jour dynamiquement le message de l'overlay
updateOverlayMessage(newMessage) {
if (this.overlayElement) {
this.overlayElement.innerText = newMessage;
}
}

// Déclenche un événement personnalisé
triggerEvent(eventName, detail) {
const event = new CustomEvent(eventName, { detail });
this.events.dispatchEvent(event);
}

// Nettoyage des ressources
cleanup() {
this.stopPolling();
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
if (this.overlayElement) {
document.body.removeChild(this.overlayElement);
}
if (this.styleElement) {
document.head.removeChild(this.styleElement);
}
}
}

0 comments on commit d5a8df9

Please sign in to comment.