Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles
, '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

Adding delayed calculation of annotation values for AdminUsers - #2359

Merged
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations
Oct 6, 2020
Merged

Adding delayed calculation of annotation values for AdminUsers#2359
jredrejo merged 1 commit into
learningequality:developfrom
jredrejo:delay_adminuser_annotations

Conversation

@jredrejo

@jredrejojredrejo commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

Description

As done in #2333 , here we're caching and delaying to be asynchronously calculated some of the annotated fields for the AdminUserViewSet

Issue Addressed (if applicable)

Slow or impossible view with thousands of users in our Studio database

Implementation Notes (optional)

Added also an api for the frontend to fetch delayed data. Example of use:
http://localhost:8080/api/admin-users/deferred_data?id__in=1,2,3,90

One task to do all the users calculation is implemented (a single user task is not needed by now):
cache_multiple_users_metadata_task

At a high level, how did you implement this?

Values are stored in the cache and recalculated when they are requested if one hour has passed since its last calculation. To avoid cache stampede the expiration time is calculated with the @cache_stampede decorator that uses a randomized gaussian function so not all the calculations are done simultaneously

General view: Calculating annotated fields for the ViewSet in an asynchronous task

when (not) to use this:

  • Using this approach delays the calculation of the annotated fields. If they are required in real time, don't use it
  • Using this approach you don't have data in the first request of the field (user, channel, etc.), instead a DEFERRED_FLAG is returned. After the task is run there's always a returned value, but it might have been calculated some time ago, depending on the expire time used in the @cache_stampede decorator
  • Using this approach you can't filter by the annotated fields

when to use this:

  • When using this approach the annotated fields are removed from the main queryset, making it much simpler, thus faster. It usually also removes group_by and order_by commands that add more searchs in the database
  • When using this approach, there is always (excepting the first request) an usable value in the redis cache that can be accessed easily
  • The implemented stampede method guaranties the value is requested in the expire interval while ensuring not all the requests are done at the same time, to distribute the database work
  • there is an api for the frontend to fetch easily the cached values
  • Tasks can be set to calculate the value for a group of items in one single task (to be shown in a table, for example), or to calculate one per task

@codecov

codecovBot commented Oct 2, 2020

Copy link
Copy Markdown

Codecov Report

Merging #2359 into develop will decrease coverage by 0.23%.
The diff coverage is 28.37%.

Impacted file tree graph

@@ Coverage Diff @@## develop #2359 +/- ##
===========================================
- Coverage 80.57% 80.33% -0.24% 
===========================================
Files 299 300 +1 Lines 15168 15238 +70 ===========================================
+ Hits 12221 12241 +20 - Misses 2947 2997 +50 
Impacted FilesCoverage Δ
...ontentcuration/contentcuration/viewsets/channel.py73.33% <0.00%> (ø)
contentcuration/contentcuration/viewsets/user.py56.28% <25.58%> (-7.87%)⬇️
contentcuration/contentcuration/utils/user.py29.62% <29.62%> (ø)
contentcuration/contentcuration/tasks.py72.72% <66.66%> (-0.16%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74754d6...723e3b8. Read the comment docs.

@rtibblesrtibbles linked an issue Oct 2, 2020 that may be closed by this pull request
@rtibbles

Copy link
Copy Markdown
Member

Could we add the PR comment to the dev docs and then merge?

@jredrejo
jredrejo merged commit f66847c into learningequality:developOct 6, 2020
@jredrejo
jredrejo deleted the delay_adminuser_annotations branch October 6, 2020 17:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize admin page

2 participants

@jredrejo@rtibbles