Added a local cache layer for an app within a workflow. This is to help with caching to laod faster
This commit is contained in:
@@ -356,11 +356,13 @@ class AppBase:
|
|||||||
self.action = json.loads(self.action)
|
self.action = json.loads(self.action)
|
||||||
self.original_action = json.loads(self.action)
|
self.original_action = json.loads(self.action)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.info(f"[DEBUG] Failed parsing action as JSON (init): {e}. NOT important if running apps with webserver. This is NOT critical.")
|
pass
|
||||||
|
|
||||||
if len(self.base_url) == 0:
|
if len(self.base_url) == 0:
|
||||||
self.base_url = self.url
|
self.base_url = self.url
|
||||||
|
|
||||||
|
self.local_storage = []
|
||||||
|
|
||||||
# Checks output for whether it should be automatically parsed or not
|
# Checks output for whether it should be automatically parsed or not
|
||||||
def run_magic_parser(self, input_data):
|
def run_magic_parser(self, input_data):
|
||||||
if not isinstance(input_data, str):
|
if not isinstance(input_data, str):
|
||||||
@@ -1034,7 +1036,6 @@ class AppBase:
|
|||||||
#self.logger.info(f"NEW PARAMS: {new_params}")
|
#self.logger.info(f"NEW PARAMS: {new_params}")
|
||||||
param_multiplier = new_params
|
param_multiplier = new_params
|
||||||
|
|
||||||
#self.logger.info("Returned with newparams of length %d", len(new_params))
|
|
||||||
#if isinstance(new_params, list) and len(new_params) == 1:
|
#if isinstance(new_params, list) and len(new_params) == 1:
|
||||||
# params = new_params[0]
|
# params = new_params[0]
|
||||||
#else:
|
#else:
|
||||||
@@ -1322,6 +1323,19 @@ class AppBase:
|
|||||||
"key": key,
|
"key": key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
newstorage = []
|
||||||
|
for item in self.local_storage:
|
||||||
|
if item["execution_id"] == self.current_execution_id and item["key"] == key:
|
||||||
|
continue
|
||||||
|
|
||||||
|
newstorage.append(item)
|
||||||
|
|
||||||
|
self.local_storage = newstorage
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("[ERROR] Failed DELETING current execution id local storage: %s" % e)
|
||||||
|
|
||||||
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
||||||
try:
|
try:
|
||||||
allvalues = response.json()
|
allvalues = response.json()
|
||||||
@@ -1343,6 +1357,19 @@ class AppBase:
|
|||||||
"value": str(value),
|
"value": str(value),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
newstorage = []
|
||||||
|
for item in self.local_storage:
|
||||||
|
if item["execution_id"] == self.current_execution_id and item["key"] == key:
|
||||||
|
continue
|
||||||
|
|
||||||
|
newstorage.append(item)
|
||||||
|
|
||||||
|
self.local_storage = newstorage
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("[ERROR] Failed SETTING current execution id local storage: %s" % e)
|
||||||
|
|
||||||
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
response = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
||||||
try:
|
try:
|
||||||
allvalues = response.json()
|
allvalues = response.json()
|
||||||
@@ -1365,12 +1392,23 @@ class AppBase:
|
|||||||
"key": key,
|
"key": key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Makes it so that loops for the same action doesn't re-ask the db unless necessary
|
||||||
|
try:
|
||||||
|
for item in self.local_storage:
|
||||||
|
if item["execution_id"] == self.current_execution_id and item["key"] == key:
|
||||||
|
# Max keeping the local cache properly for 5 seconds due to workflow continuations
|
||||||
|
elapsed_time = time.time() - item["time_set"]
|
||||||
|
if elapsed_time > 5:
|
||||||
|
break
|
||||||
|
|
||||||
|
return item["data"]
|
||||||
|
except Exception as e:
|
||||||
|
print("[ERROR] Failed getting current execution id local storage: %s" % e)
|
||||||
|
|
||||||
value = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
value = requests.post(url, json=data, verify=False, proxies=self.proxy_config)
|
||||||
try:
|
try:
|
||||||
allvalues = value.json()
|
allvalues = value.json()
|
||||||
self.logger.info("VAL1: ", allvalues)
|
|
||||||
allvalues["key"] = key
|
allvalues["key"] = key
|
||||||
self.logger.info("VAL2: ", allvalues)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsedvalue = json.loads(allvalues["value"])
|
parsedvalue = json.loads(allvalues["value"])
|
||||||
@@ -1378,6 +1416,14 @@ class AppBase:
|
|||||||
except:
|
except:
|
||||||
self.logger.info("Parsing of value as JSON failed. Continue anyway!")
|
self.logger.info("Parsing of value as JSON failed. Continue anyway!")
|
||||||
|
|
||||||
|
try:
|
||||||
|
newdata = json.loads(json.dumps(data))
|
||||||
|
newdata["time_set"] = time.time()
|
||||||
|
newdata["data"] = allvalues
|
||||||
|
self.local_storage.append(newdata)
|
||||||
|
except Exception as e:
|
||||||
|
print("[ERROR] Failed in local storage append: %s" % e)
|
||||||
|
|
||||||
return allvalues
|
return allvalues
|
||||||
except:
|
except:
|
||||||
self.logger.info("Value couldn't be parsed, or json dump of value failed")
|
self.logger.info("Value couldn't be parsed, or json dump of value failed")
|
||||||
@@ -1484,7 +1530,6 @@ class AppBase:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
self.action = copy.deepcopy(action)
|
self.action = copy.deepcopy(action)
|
||||||
self.logger.info(f"[DEBUG] Sending starting action result (EXECUTING). Param replace: {replace_params}")
|
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -2721,7 +2766,8 @@ class AppBase:
|
|||||||
|
|
||||||
#self.logger.info("VALUE: %s" % parameter["value"])
|
#self.logger.info("VALUE: %s" % parameter["value"])
|
||||||
else:
|
else:
|
||||||
self.logger.info(f"[ERROR] Not running static variant regex parsing (slow) on value with length {len(parameter['value'])}. Max is 5Mb~.")
|
#self.logger.info(f"[ERROR] Not running static variant regex parsing (slow) on value with length {len(parameter['value'])}. Max is 5Mb~.")
|
||||||
|
pass
|
||||||
|
|
||||||
if parameter["variant"] == "WORKFLOW_VARIABLE":
|
if parameter["variant"] == "WORKFLOW_VARIABLE":
|
||||||
self.logger.info("[DEBUG] Handling workflow variable")
|
self.logger.info("[DEBUG] Handling workflow variable")
|
||||||
@@ -3204,7 +3250,6 @@ class AppBase:
|
|||||||
try:
|
try:
|
||||||
self.original_action = json.loads(json.dumps(action))
|
self.original_action = json.loads(json.dumps(action))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
#self.logger.info(f"[ERROR] Failed parsing action as JSON to original action. This COULD have bad effects on LOOPED executions: {e}")
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# calltimes is used to handle forloops in the app itself.
|
# calltimes is used to handle forloops in the app itself.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
IconButton,
|
IconButton,
|
||||||
|
Chip,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
@@ -39,6 +40,7 @@ import {
|
|||||||
//import { useAlert
|
//import { useAlert
|
||||||
import { typecost, typecost_single, } from "../views/HandlePaymentNew.jsx";
|
import { typecost, typecost_single, } from "../views/HandlePaymentNew.jsx";
|
||||||
import BillingStats from "../components/BillingStats.jsx";
|
import BillingStats from "../components/BillingStats.jsx";
|
||||||
|
import { handlePayasyougo } from "../views/HandlePaymentNew.jsx"
|
||||||
|
|
||||||
const Billing = (props) => {
|
const Billing = (props) => {
|
||||||
const { globalUrl, userdata, serverside, billingInfo, stripeKey, selectedOrganization, handleGetOrg, } = props;
|
const { globalUrl, userdata, serverside, billingInfo, stripeKey, selectedOrganization, handleGetOrg, } = props;
|
||||||
@@ -404,10 +406,32 @@ const Billing = (props) => {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<div style={{display: "flex"}}>
|
<div style={{display: "flex"}}>
|
||||||
|
{top_text === "Base Cloud Access" && userdata.has_card_available === true ?
|
||||||
|
<Chip
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#f86a3e",
|
||||||
|
paddingLeft: 5,
|
||||||
|
paddingRight: 5,
|
||||||
|
height: 28,
|
||||||
|
cursor: "pointer",
|
||||||
|
borderColor: "#3d3f43",
|
||||||
|
color: "white",
|
||||||
|
marginTop: 10,
|
||||||
|
marginRight: 30,
|
||||||
|
border: "1px solid rgba(255,255,255,0.3)",
|
||||||
|
}}
|
||||||
|
label={"Unlimited"}
|
||||||
|
onClick={() => {
|
||||||
|
console.log("Clicked chip")
|
||||||
|
}}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
: null}
|
||||||
<Typography variant="h6" style={{ marginTop: 10, marginBottom: 10, flex: 5, }}>
|
<Typography variant="h6" style={{ marginTop: 10, marginBottom: 10, flex: 5, }}>
|
||||||
{top_text}
|
{top_text}
|
||||||
</Typography>
|
</Typography>
|
||||||
{isCloud && highlight === true ?
|
{isCloud && highlight === true && top_text !== "Base Cloud Access" ?
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="Sign EULA"
|
title="Sign EULA"
|
||||||
placement="top"
|
placement="top"
|
||||||
@@ -534,7 +558,11 @@ const Billing = (props) => {
|
|||||||
{subscription.name.includes("Scale") ?
|
{subscription.name.includes("Scale") ?
|
||||||
""
|
""
|
||||||
:
|
:
|
||||||
"You are not subscribed to any plan and are using the free plan with max 10,000 app runs per month. Upgrade to deactivate this limit."
|
|
||||||
|
userdata.has_card_available === true ?
|
||||||
|
"While you have a card attached to your account, Shuffle will no longer prevent workflows from running. Billing will occur at the start of each month."
|
||||||
|
:
|
||||||
|
`You are not subscribed to any plan and are using the free plan with max 10,000 app runs per month. Upgrade to deactivate this limit. Your organisations manager email is ${selectedOrganization.org}.`
|
||||||
}
|
}
|
||||||
</Typography>
|
</Typography>
|
||||||
{/*isCloud ?
|
{/*isCloud ?
|
||||||
@@ -549,10 +577,49 @@ const Billing = (props) => {
|
|||||||
Add Payment Method
|
Add Payment Method
|
||||||
</Button>
|
</Button>
|
||||||
: null*/}
|
: null*/}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
fullWidth
|
||||||
|
disabled={false}
|
||||||
|
variant="outlined"
|
||||||
color="primary"
|
color="primary"
|
||||||
style={{ marginTop: 20, marginBottom: 10, }}
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 40,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "white",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (isCloud) {
|
||||||
|
handlePayasyougo(userdata)
|
||||||
|
//navigate("/pricing?tab=cloud&highlight=true")
|
||||||
|
} else {
|
||||||
|
//window.open("https://shuffler.io/pricing?tab=onprem&highlight=true", "_blank")
|
||||||
|
handlePayasyougo()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{userdata.has_card_available === true ?
|
||||||
|
"Manage Card Details"
|
||||||
|
:
|
||||||
|
"Add Card Details"
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
{userdata.has_card_available === true ?
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
disabled={false}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 40,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "white",
|
||||||
|
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)",
|
||||||
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
navigate("/pricing?tab=cloud&highlight=true")
|
navigate("/pricing?tab=cloud&highlight=true")
|
||||||
@@ -561,8 +628,24 @@ const Billing = (props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Upgrade now
|
Upgrade plan
|
||||||
</Button>
|
</Button>
|
||||||
|
: null}
|
||||||
|
|
||||||
|
{userdata.has_card_available === false ?
|
||||||
|
<img
|
||||||
|
src="/images/stripenew.png"
|
||||||
|
style={{
|
||||||
|
margin: "auto",
|
||||||
|
marginTop: 20,
|
||||||
|
width: 100,
|
||||||
|
marginLeft: "35%",
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
clip: "rect(30px, 30px, 30px, 30px)",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
: null}
|
||||||
</span>
|
</span>
|
||||||
: null}
|
: null}
|
||||||
{showSupport ?
|
{showSupport ?
|
||||||
@@ -1046,7 +1129,7 @@ const Billing = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{isCloud &&
|
{/*isCloud &&
|
||||||
selectedOrganization.partner_info !== undefined &&
|
selectedOrganization.partner_info !== undefined &&
|
||||||
selectedOrganization.partner_info.reseller === true ? (
|
selectedOrganization.partner_info.reseller === true ? (
|
||||||
<div style={{ marginTop: 30, marginBottom: 200 }}>
|
<div style={{ marginTop: 30, marginBottom: 200 }}>
|
||||||
@@ -1230,7 +1313,7 @@ const Billing = (props) => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null*/}
|
||||||
<div style={{ marginTop: 30, }}>
|
<div style={{ marginTop: 30, }}>
|
||||||
<Typography
|
<Typography
|
||||||
style={{ marginTop: 40, marginLeft: 10, marginBottom: 5 }}
|
style={{ marginTop: 40, marginLeft: 10, marginBottom: 5 }}
|
||||||
|
|||||||
Reference in New Issue
Block a user