This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

[WIP] upload scheduled query metadata - #504

Merged
n-riesco merged 6 commits into
masterfrom
metadata
Aug 3, 2018
Merged

[WIP] upload scheduled query metadata#504
n-riesco merged 6 commits into
masterfrom
metadata

Conversation

@briandennis

@briandennisbriandennis commented Jul 31, 2018

Copy link
Copy Markdown
Contributor

closes#503

TODO:

  • figure out why chart studio still shows incorrect refresh interval despite being set correctly (as far as I can tell)
  • research issues related to metadata request failing after updating query content and look into rolling back if needed

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Process note: could you please target the 3.0-onprem branch instead of master for stuff related to the release? We'll merge that branch into master when it goes gold :)

Comment threadbackend/routes.js
query,
connectionId,
requestor,
cronInterval = null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, why setting the default to 'null'?

return 60;
} else if (cronInterval === '*/5 * * * *') {
return 60 * 5;
} else if (cronInterval.match(/\S+? \* \* \* \*/)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this throws when cronInterval is null

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Fixing the issue with mapCronToRefresh fixes the issue Chart Studio not showing the grid metadata:

diff --git a/backend/utils/cronUtils.js b/backend/utils/cronUtils.js
index f9ce325..c896996 100644
--- a/backend/utils/cronUtils.js+++ b/backend/utils/cronUtils.js@@ -23,14 +23,16 @@ export function mapRefreshToCron (refreshInterval) {
}
export function mapCronToRefresh (cronInterval) {
- if (cronInterval === '* * * * *') {- return 60;- } else if (cronInterval === '*/5 * * * *') {- return 60 * 5;- } else if (cronInterval.match(/\S+? \* \* \* \*/)) {- return 60 * 60;- } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {- return 60 * 60 * 24;+ if (cronInterval) {+ if (cronInterval === '* * * * *') {+ return 60;+ } else if (cronInterval === '*/5 * * * *') {+ return 60 * 5;+ } else if (cronInterval.match(/\S+? \* \* \* \*/)) {+ return 60 * 60;+ } else if (cronInterval.match(/\S+? \S+? \* \* \*/)) {+ return 60 * 60 * 24;+ }
}
// default to weekly
@@ -47,4 +49,4 @@ function computeMinutes (now) {
}
return minutes.join(',');
-}
\ No newline at end of file
+}

image


While testing sometimes I get:

image

image

When this happens, I restart Falcon and indeed the query has been deleted (as one would expect when the associated grid has been deleted).

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis And this fixes the issue that was causing refreshInterval to be always set to weekly.

diff --git a/backend/persistent/QueryScheduler.js b/backend/persistent/QueryScheduler.js
index 63375db..139db44 100644
--- a/backend/persistent/QueryScheduler.js+++ b/backend/persistent/QueryScheduler.js@@ -23,8 +23,6 @@ import {
updateGrid
} from './plotly-api.js';
-const DEFAULT_REFRESH_INTERVAL = 60 * 60 * 24 * 7;-
class QueryScheduler {
constructor() {
this.scheduleQuery = this.scheduleQuery.bind(this);
@@ -100,7 +98,7 @@ class QueryScheduler {
requestor,
fid,
uids,
- refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,+ refreshInterval,
cronInterval,
query,
connectionId

@n-riesco

Copy link
Copy Markdown
Contributor

@briandennis Please, ignore my comment about the random errors caused by deleted grids. I was using a query left behind by the unit tests.

@nicolaskruchten

Copy link
Copy Markdown
Contributor

note that the connectorUrl that gets pushed into metadata shouldn't be https://default:9494 as in the screenshot above ... it should be something more like "connectorUrl": "https://nicolas-026480bf-62bf-4b19-be6c-3.plotly-connector.com:9495",

@n-riesco

Copy link
Copy Markdown
Contributor

@nicolaskruchten please, ignore that screenshot, it was generated using a queries.yaml left behind by the unit tests.

@n-riesco

Copy link
Copy Markdown
Contributor

This is how it looks like with a query scheduled from Falcon:

image

@nicolaskruchten

Copy link
Copy Markdown
Contributor

@briandennis do you need any help getting this guy over the finish line?

@briandennis

Copy link
Copy Markdown
ContributorAuthor

@nicolaskruchten apologies for the delayed fixes here, was traveling these past few days. I believe the only remaining work is looking into whether or not the metadata request failure leaves the grid in a recoverable state. Investigating that now...

fid,
uids,
refreshInterval: refreshInterval || DEFAULT_REFRESH_INTERVAL,
refreshInterval: refreshInterval || mapCronToRefresh(cronInterval),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@briandennis

Copy link
Copy Markdown
ContributorAuthor

After testing with a backend that purposely fails when updating metadata, here's what I've found:

Creating a new scheduled query (queryAndCreate)

  • a new grid is created with the query content but with no metadata
  • the query is not scheduled or persisted in Falcon
  • after a successful retry, a new grid will be tied to the query and the detached grid from the failed attempt will remain
  • rollback operation required: delete the detached grid

Updating an existing scheduled query (queryAndUpdate)

  • the existing grid is updated with the new content (potentially out of sync with the original query)
  • old metadata remains intact
  • original scheduled query will continue to run on it's original schedule
  • after a successful retry, everything will be updated correctly and the state would be the same as if the failure never happened
  • rollback operation required: load the grid's original content before starting the update and repopulate the grid with it after detecting a metadata upload failure

Some things to consider regarding a rollback solution:

  • metadata failure should be a very exceptional case (bad query/connection parameters would cause query execution to fail first, bad authentication creds would cause the grid content request to fail first)
  • if the problem is network related, the rollback requests would likely still fail
  • in both cases, the failure is recoverable (subsequent successful requests resolve inconsistencies and the only side effect would be the addition of the detached grid in the case of create)

@n-riesco@nicolaskruchten let me know how you want to proceed 🙂

@nicolaskruchten

Copy link
Copy Markdown
Contributor

Generally, I think I would be OK with just letting the user know that something odd had happened with the metadata and that they should hit save again, instead of trying to roll things back etc.

In case 1 there is no metadata, which means that the user can't edit the query from the webapp (meh, the Falcon UI is better) and that the grid isn't indexed as being 'live' (meh, not great but not the end of the world).

In case 2 there is metadata which is wrong, so a user editing the query from the webapp would have an incorrect starting point. This is not great, but again we're going to be discouraging this pattern.

In either case, informing the user and getting them to re-save is good enough I feel, given how rare we expect this situation to be.

@n-riesco
n-riesco merged commit 9e5badb into masterAug 3, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduling should also add SQL query to grid metadata

3 participants

@briandennis@nicolaskruchten@n-riesco