UNPKG

pando-computing

Version:

Distribute processing of a stream of items to volunteers on the web.

299 lines (276 loc) 10 kB
<html> <head> <link rel="stylesheet" href="bootstrap.min.css"> <style> body { font-family: "Helvetica Neue", helvetica, arial; padding: 15px; } ul { list-style: none; margin: 0; padding: 0; } ul li { line-height: 1.4; } </style> <script> localStorage.debug='webrtc-bootstrap*,simple-peer' _log = console.log.bind(console) console.log = function (s) { var li = document.createElement('li'); li.innerHTML = s; document.querySelector('#console').appendChild(li); _log(s) } </script> </head> <body> <!-- Modal Device Selection --> <div class="modal fade" id="modalDeviceSelection" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="modalDeviceSelectionLabel">Device Selection</h5> </div> <div class="modal-body"> <div class="input-group mb-3"> <div class="input-group-prepend"> <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Device</button> <div class="dropdown-menu" id='modal-device-list'> </div> </div> <input id='modal-device-name' type="text" class="form-control" aria-label="Text input with dropdown button" > </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" onclick="submit(null, document.getElementById('modal-device-name')); countdown(seconds, 'Connecting', start); $('#modalDeviceSelection').modal('toggle')">Save</button> </div> </div> </div> </div> <div id='visualization'></div> <h1>status</h1> <div class="input-group mb-3"> <div class="input-group-prepend"> <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Device</button> <div class="dropdown-menu" id='device-list'> </div> </div> <input id='device-name' type="text" class="form-control" aria-label="Text input with dropdown button" onkeypress="return submit(event, document.getElementById('device-name'))"> </div> <div class="input-group"> <div class="input-group-prepend"> <span class="input-group-text">Throughput</span> </div> <input type="text" class="form-control" id="throughput" placeholder="0.0"> </div> <div class="input-group"> <div class="input-group-prepend"> <span class="input-group-text">CPU Load</span> </div> <input type="text" class="form-control" id="cpu-usage" placeholder=""> </div> <div class="input-group"> <div class="input-group-prepend"> <span class="input-group-text">Data Transfer Load</span> </div> <input type="text" class="form-control" id="data-transfer-load" placeholder=""> </div> <p><a id='status'></a></p> <h1>console.log</h1> <ul id='console'></ul> <script src='simplewebsocket.min.js'></script> <script src='volunteer.js'></script> <script src="jquery.min.js"></script> <script src="popper.min.js"></script> <script src="bootstrap.min.js"></script> <script src='config.js'></script> <script> var secure = location.origin.indexOf('https:\/\/') > -1 var host = null if (secure) { host = location.origin.replace(/^https:\/\//, '') } else { host = location.origin.replace(/^http:\/\//, '') } window.pando.config.host = host var seconds = 3 var restarting = false var connectTimeout = null var reporter = null var processor = null function protocol () { if (location.hash.includes('protocol=websocket')) { return 'protocol=websocket' } else if (location.hash.includes('protocol=webrtc')) { return 'protocol=webrtc' } else { return 'protocol=websocket' } } function restart () { if (restarting) return console.log('restart()') document.querySelector('#status').textContent = 'Restarting' restarting = true if (processor) processor.close() processor = null countdown(seconds, 'Connecting', start) } function countdown (seconds, actionText, cb) { if (seconds <= 0) { document.querySelector('#status').textContent = actionText; cb() } else { document.querySelector('#status').textContent = actionText + ' in ' + seconds + ' seconds' setTimeout(function () { countdown(seconds-1, actionText, cb) }, 1000) } } // Add default list of devices var deviceList = [ 'MacBook Air 2011', 'iPhone SE', 'MacBook Pro 2016', 'Samsung Galaxy S6', 'Samsung Galaxy S7', 'OPPO F1FX 2016', 'Lenovo P2a42 2016', 'Huawei P10 lite 2017', 'Wileyfox Storm 2016', 'iPhone 7', 'LG G6 H870 2017', 'iPad A1822 (5th Gen) 2017', 'Samsung A3 2016', 'Samsung Galaxy S7', 'iPhone 6S' ] deviceList.sort() deviceListMenu = document.getElementById('device-list') deviceList.forEach(function addItem (name) { var a = document.createElement('a') a.className = 'dropdown-item' a.innerText = name var id = name.replace(/\s/g, '_') a.href = '#' + protocol() + ';device=' + id + ';' a.id = id a.onclick = function () { replaceDeviceName(name) } deviceListMenu.appendChild(a) }) modalDeviceListMenu = document.getElementById('modal-device-list') deviceList.forEach(function addItem (name) { var a = document.createElement('a') a.className = 'dropdown-item' a.innerText = name var id = name.replace(/\s/g, '_') a.href = '#' + protocol() + ';device=' + id + ';' a.id = id a.onclick = function () { replaceDeviceName(name) var deviceName = document.getElementById('modal-device-name') deviceName.value = name } modalDeviceListMenu.appendChild(a) }) function getDeviceName() { if (location.hash.includes('device=')) { var m = location.hash.match('device=([^;]*);') var deviceName = document.getElementById('device-name') deviceName.value = m[1].replace(/_/g, ' ') return deviceName.value } return '' } function replaceDeviceName(name) { var deviceName = document.getElementById('device-name') deviceName.value = name } function submit(event, deviceNameInput) { if (event !== null && event.keyCode !== 13) return var hash = location.hash.replace(/^#*;*/, '#;') document.getElementById('device-name').value = deviceNameInput.value var deviceName = deviceNameInput.value.replace(/\s/g, '_') if (hash.includes('device=')) { hash = hash.replace(/device=.*;/, 'device=' + deviceName + ';') } else { hash = hash + 'device=' + deviceName + ';' } var url = location.protocol + '\/\/' + location.host + '\/' + hash location.assign(url) } if (getDeviceName().length < 1) { $('#modalDeviceSelection').modal('show') } </script> <script src='bundle.js'></script> <script> function start () { console.log('start()') processor = null window.pando.config.secure = secure setTimeout(function () { if (location.hash.includes('protocol=webrtc')) { console.log('connecting over WebRTC') window.pando.config.protocol = 'webrtc' processor = volunteer['webrtc'](host, bundle, window.pando.config) } else { console.log('connecting over WebSocket') var protocol = secure ? 'wss://' : 'ws://' window.pando.config.protocol = 'websocket' processor = volunteer['websocket'](protocol + host + '/volunteer', bundle) } processor.on('status', function (summary) { if (reporter) { console.log('reporting status') reporter.send(JSON.stringify(summary)) } }) processor.on('close', function () { restart() if (reporter) { console.log('reporting processor closed') reporter.send(JSON.stringify({ type: 'STATUS', closed: true })) } }) processor.on('error', function (err) { restart() if (reporter) { console.log('reporting processor error') reporter.send(JSON.stringify({ type: 'STATUS', error: err })) } }) processor.on('ready', function () { console.log('cleared restart timeout') document.querySelector('#status').textContent = 'Connected' clearTimeout(connectTimeout) restarting = false }) // If connection does not succeed, keep retrying until it does console.log('setting restart timeout') connectTimeout = setTimeout(function () { console.log('connection timeout') if (reporter) { console.log('reporting connection timeout') reporter.send(JSON.stringify({ type: 'STATUS', error: 'Connection timeout, restarting' })) } restarting = false restart() }, 30 * 1000) window.pando.processor = processor }, Math.floor(Math.random() * 1000)) // Random delay of up to 1s to avoid all nodes connecting at the same time } if (getDeviceName().length > 0) { countdown(0, 'Connecting', start) } if (window.pando.config.globalMonitoring) { var protocol = secure ? 'wss://' : 'ws://' var socket = SimpleWebsocket(protocol + host + '/monitoring/processor') socket.on('connect', function () { console.log('reporter connected') reporter = socket }) } </script> </body> </html>