Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Issue/718 create worker for scanning #910

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 114 additions & 5 deletions assets/js/Components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AboutModal from './AboutModal'
import { View } from '@instructure/ui-view'
import Api from '../Services/Api'
import MessageTray from './MessageTray'
import CourseUpdateProgress from './CourseUpdateProgress'
import FilesPage from './FilesPage'
import SummaryBar from './SummaryBar'

Expand All @@ -20,14 +21,20 @@ class App extends React.Component {
this.settings = props.settings
this.reportHistory = []
this.messages = props.messages
this.newReportInterval = 5000

this.state = {
report: this.initialReport,
navigation: 'welcome',
modal: null,
syncComplete: false,
hasNewReport: false,
progress: 0,
totalIssues: 0,
scanCompleted: false,
contentUpdateCompleted: false,
title: "",
updateInterval: 0,
scanInterval: 0,
}

this.handleNavigation = this.handleNavigation.bind(this)
Expand All @@ -41,6 +48,11 @@ class App extends React.Component {
this.handleCourseRescan = this.handleCourseRescan.bind(this)
this.handleNewReport = this.handleNewReport.bind(this)
this.resizeFrame = this.resizeFrame.bind(this)
this.pollBackgroundWorker = this.pollBackgroundWorker.bind(this)
this.fetchLoadData = this.fetchLoadData.bind(this)
this.fetchUpdateData = this.fetchUpdateData.bind(this)
this.getReport = this.getReport.bind(this)
this.getLatestReport = this.getLatestReport.bind(this)
}

render() {
Expand All @@ -60,7 +72,12 @@ class App extends React.Component {
}

<MessageTray messages={this.messages} t={this.t} clearMessages={this.clearMessages} hasNewReport={this.state.syncComplete} />


<CourseUpdateProgress
progress={this.state.progress}
contentUpdateCompleted={this.state.contentUpdateCompleted}
title = {this.state.title}/>

<main role="main">
{('welcome' === this.state.navigation) &&
<WelcomePage
Expand Down Expand Up @@ -127,14 +144,32 @@ class App extends React.Component {

this.scanCourse()
.then((response) => response.json())
.then(this.handleNewReport)
.then(() => this.getContentUpdate())
.then(() => this.pollBackgroundWorker())
.then(() => this.getReport())

// update iframe height on resize
window.addEventListener("resize", this.resizeFrame);

this.resizeFrame();
}

getReport() {
if(this.state.scanCompleted === true) {
this.getLatestReport()
.then((response) => response.json())
.then(this.handleNewReport)
}
else {
setTimeout(this.getReport, 500);
}
}

getLatestReport() {
let api = new Api(this.settings)
return api.getLatestReport(this.settings.course.id)
}

componentWillUnmount() {
window.removeEventListener('resize', this.resizeFrame);
}
Expand All @@ -154,14 +189,88 @@ class App extends React.Component {

handleCourseRescan() {
if (this.state.hasNewReport) {
this.setState({ hasNewReport: false, syncComplete: false })
this.setState({hasNewReport: false,
syncComplete: false,
contentUpdateCompleted: false,
scanCompleted: false,
progress: 0})
this.scanCourse()
.then((response) => response.json())
.then(this.handleNewReport)
.then(() => this.getContentUpdate())
.then(() => this.pollBackgroundWorker())
.then(() => this.getReport())
}
this.forceUpdate()
}

// As the worker process updates UDOIT with the latest content items, this method checks on whether or not
// This process has been completed
fetchUpdateData() {
fetch(`http://${window.location.hostname}:8000/udoit3/api/progress`)
taheralfayad marked this conversation as resolved.
Show resolved Hide resolved
.then(response => response.json())
.then(data => {
this.setState({
progress: data.progress,
title: data.title
}, () => {
const progress = this.state.progress
const interval = this.state.updateInterval
const title = this.state.title
if(title != "Getting content from Canvas") {
clearInterval(interval);
this.state.updateInterval = null
this.state.contentUpdateCompleted = true
}
});
})
.catch(error => {
console.error('Error:', error);
});
}

fetchLoadData() {
fetch(`http://${window.location.hostname}:8000/udoit3/api/progress`)
.then(response => response.json())
.then(data => {
this.setState({
progress: data.progress,
total: data.total,
title: data.title
}, () => {
const progress = this.state.progress
const total = this.state.total
const interval = this.state.scanInterval
if(progress === total) {
clearInterval(interval);
this.state.scanInterval = null
this.state.scanCompleted = true
}
});
})
.catch(error => {
console.error('Error:', error);
});
}

getContentUpdate() {
const interval = setInterval(() => {
this.fetchUpdateData();
}, 1000)
this.setState({updateInterval: interval})
}

pollBackgroundWorker() {
if (this.state.contentUpdateCompleted) {
const interval = setInterval(() => {
this.fetchLoadData()
}, 1000)
this.setState({scanInterval: interval})
}
else {
setTimeout(this.pollBackgroundWorker, 500);
}
}

handleNewReport(data) {
let report = this.state.report
let hasNewReport = this.state.hasNewReport
Expand Down
41 changes: 41 additions & 0 deletions assets/js/Components/CourseUpdateProgress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import { Spinner } from '@instructure/ui-spinner'
import { Alert } from '@instructure/ui-alerts'

import Classes from '../../css/app.css'

class CourseUpdateProgress extends React.Component {
constructor(props) {
super(props)
this.checkProgress = this.checkProgress.bind(this)
this.state = {
completed: false,
}
}

render() {
return (
this.checkProgress() && !this.props.contentUpdateCompleted &&
<div>
<Alert
variant="info"
margin="small large"
>
Updated {this.props.progress} items so far...
<Spinner size="x-small" margin="0 small" renderTitle="Loading" />
</Alert>
</div>
)
}

checkProgress() {
if(this.props.title != "Getting content from Canvas") {
setTimeout(() => {
this.props.contentUpdateCompleted = false
}, 2000);
}
return true
}
}

export default CourseUpdateProgress
16 changes: 16 additions & 0 deletions assets/js/Services/Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default class Api {
this.apiUrl = `https://${window.location.hostname}`;
this.endpoints = {
getReport: '/api/courses/{course}/reports/{report}',
getLatestReport: '/api/sync/getLatestReport/{course}',
getReportHistory: '/api/courses/{course}/reports',
saveIssue: '/api/issues/{issue}/save',
resolveIssue: '/api/issues/{issue}/resolve',
Expand Down Expand Up @@ -233,6 +234,21 @@ export default class Api {
})
}

getLatestReport(courseId)
{
const authToken = this.getAuthToken()
let url = `${this.apiUrl}${this.endpoints.getLatestReport}`
url = url.replace('{course}', courseId)

return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-AUTH-TOKEN': authToken,
},
})
}

scanContent(contentId)
{
const authToken = this.getAuthToken()
Expand Down
2 changes: 1 addition & 1 deletion build/nginx/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
service nginx start
php-fpm
php-fpm
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"symfony/browser-kit": "6.0.*",
"symfony/css-selector": "6.0.*",
"symfony/debug-bundle": "6.0.*",
"symfony/maker-bundle": "^1.0",
"symfony/maker-bundle": "^1.49",
"symfony/phpunit-bridge": "^6.0",
"symfony/stopwatch": "6.0.*",
"symfony/web-profiler-bundle": "6.0.*"
Expand Down
20 changes: 10 additions & 10 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/packages/messenger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ framework:
#'App\Message\BackgroundQueueItem': async_priority_low
'App\Message\PriorityQueueItem': sync
'App\Message\BackgroundQueueItem': sync
'App\Message\ScanMessage': async_priority_high
10 changes: 10 additions & 0 deletions docker-compose.nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ services:
- type: bind
source: ./build/nginx/php-custom.ini
target: /usr/local/etc/php/conf.d/php-custom.ini
image: php
env_file:
- .env
composer:
Expand All @@ -66,6 +67,15 @@ services:
yarn install &&
yarn build'

messenger-consume:
image: php
volumes:
- ./:/var/www/html
command: >
bash -c "sleep 15 && bin/console messenger:consume async_priority_high"
depends_on:
- db

volumes:
web:
dbdata:
Loading