mirror of
https://github.com/unraid/webgui.git
synced 2026-01-06 01:29:54 -06:00
Tackle Nchan out of memory
These changes prevent Nchan issues when nginx is restarted. In my testing it works most of the time, but opening many browsers to the same GUI still gives the issue, though this is definitely an improvement over the current implementation.
This commit is contained in:
@@ -105,14 +105,10 @@ if (!file_exists($notes)) file_put_contents($notes,shell_exec("$docroot/plugins/
|
||||
<script>
|
||||
String.prototype.actionName = function(){return this.split(/[\\/]/g).pop();}
|
||||
String.prototype.channel = function(){return this.split(':')[1].split(',').findIndex((e)=>/\[\d\]/.test(e));}
|
||||
NchanSubscriber.prototype.monitor = function(){subscribers.push(this);}
|
||||
|
||||
|
||||
Shadowbox.init({skipSetup:true});
|
||||
context.init();
|
||||
|
||||
// list of nchan subscribers to start/stop at focus change
|
||||
var subscribers = [];
|
||||
|
||||
// server uptime
|
||||
var uptime = <?=strtok(exec("cat /proc/uptime"),' ')?>;
|
||||
var expiretime = <?=_var($var,'regTy')=='Trial'||strstr(_var($var,'regTy'),'expired')?_var($var,'regTm2'):0?>;
|
||||
@@ -144,6 +140,7 @@ function pauseEvents(id) {
|
||||
if (!id || i==id) clearTimeout(timer);
|
||||
});
|
||||
}
|
||||
|
||||
function resumeEvents(id,delay) {
|
||||
var startDelay = delay||50;
|
||||
$.each(timers, function(i,timer) {
|
||||
@@ -151,9 +148,11 @@ function resumeEvents(id,delay) {
|
||||
startDelay += 50;
|
||||
});
|
||||
}
|
||||
|
||||
function plus(value,single,plural,last) {
|
||||
return value>0 ? (value+' '+(value==1?single:plural)+(last?'':', ')) : '';
|
||||
}
|
||||
|
||||
function updateTime() {
|
||||
var now = new Date();
|
||||
var days = parseInt(uptime/86400);
|
||||
@@ -183,6 +182,7 @@ function updateTime() {
|
||||
}
|
||||
setTimeout(updateTime,1000);
|
||||
}
|
||||
|
||||
function refresh(top) {
|
||||
if (typeof top === 'undefined') {
|
||||
for (var i=0,element; element=document.querySelectorAll('input,button,select')[i]; i++) {element.disabled = true;}
|
||||
@@ -193,11 +193,13 @@ function refresh(top) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
function initab(page) {
|
||||
$.removeCookie('one');
|
||||
$.removeCookie('tab');
|
||||
if (page != null) location.replace(page);
|
||||
}
|
||||
|
||||
function settab(tab) {
|
||||
<?switch ($myPage['name']):?>
|
||||
<?case'Main':?>
|
||||
@@ -213,6 +215,7 @@ function settab(tab) {
|
||||
$.cookie('one',tab);
|
||||
<?endswitch;?>
|
||||
}
|
||||
|
||||
function done(key) {
|
||||
var url = location.pathname.split('/');
|
||||
var path = '/'+url[1];
|
||||
@@ -220,10 +223,12 @@ function done(key) {
|
||||
$.removeCookie('one');
|
||||
location.replace(path);
|
||||
}
|
||||
|
||||
function chkDelete(form, button) {
|
||||
button.value = form.confirmDelete.checked ? "<?=_('Delete')?>" : "<?=_('Apply')?>";
|
||||
button.disabled = false;
|
||||
}
|
||||
|
||||
function makeWindow(name,height,width) {
|
||||
var top = (screen.height-height)/2;
|
||||
if (top < 0) {top = 0; height = screen.availHeight;}
|
||||
@@ -231,6 +236,7 @@ function makeWindow(name,height,width) {
|
||||
if (left < 0) {left = 0; width = screen.availWidth;}
|
||||
return window.open('',name,'resizeable=yes,scrollbars=yes,height='+height+',width='+width+',top='+top+',left='+left);
|
||||
}
|
||||
|
||||
function openBox(cmd,title,height,width,load,func,id) {
|
||||
// open shadowbox window (run in foreground)
|
||||
// included for legacy purposes, replaced by openPlugin
|
||||
@@ -239,6 +245,7 @@ function openBox(cmd,title,height,width,load,func,id) {
|
||||
var options = load ? (func ? {modal:true,onClose:function(){setTimeout(func+'('+'"'+(id||'')+'")');}} : {modal:true,onClose:function(){location.reload();}}) : {modal:false};
|
||||
Shadowbox.open({content:run, player:'iframe', title:title, height:Math.min(screen.availHeight,800), width:Math.min(screen.availWidth,1200), options:options});
|
||||
}
|
||||
|
||||
function openWindow(cmd,title,height,width) {
|
||||
// open regular window (run in background)
|
||||
// included for legacy purposes, replaced by openTerminal
|
||||
@@ -256,6 +263,7 @@ function openWindow(cmd,title,height,width) {
|
||||
makeWindow(window_name,height,width);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function openTerminal(tag,name,more) {
|
||||
if (/MSIE|Edge/.test(navigator.userAgent)) {
|
||||
swal({title:"_(Unsupported Feature)_",text:"_(Sorry, this feature is not supported by MSIE/Edge)_.<br>_(Please try a different browser)_",type:'error',html:true,animation:'none',confirmButtonText:"_(Ok)_"});
|
||||
@@ -267,6 +275,7 @@ function openTerminal(tag,name,more) {
|
||||
var socket = ['ttyd','syslog'].includes(tag) ? '/webterminal/'+tag+'/' : '/logterminal/'+name+(more=='.log'?more:'')+'/';
|
||||
$.get('/webGui/include/OpenTerminal.php',{tag:tag,name:name,more:more},function(){setTimeout(function(){tty_window.location=socket; tty_window.focus();},200);});
|
||||
}
|
||||
|
||||
function bannerAlert(text,cmd,plg,func,start) {
|
||||
$.post('/webGui/include/StartCommand.php',{cmd:cmd,pid:1},function(pid) {
|
||||
if (pid == 0) {
|
||||
@@ -303,6 +312,7 @@ function bannerAlert(text,cmd,plg,func,start) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openPlugin(cmd,title,plg,func,start=0,button=0) {
|
||||
// start = 0 : run command only when not already running (default)
|
||||
// start = 1 : run command unconditionally
|
||||
@@ -326,6 +336,7 @@ function openPlugin(cmd,title,plg,func,start=0,button=0) {
|
||||
$('button.confirm').prop('disabled',button!=0);
|
||||
});
|
||||
}
|
||||
|
||||
function openDocker(cmd,title,plg,func,start=0,button=0) {
|
||||
// start = 0 : run command only when not already running (default)
|
||||
// start = 1 : run command unconditionally
|
||||
@@ -349,6 +360,7 @@ function openDocker(cmd,title,plg,func,start=0,button=0) {
|
||||
$('button.confirm').prop('disabled',button==0);
|
||||
});
|
||||
}
|
||||
|
||||
function openVMAction(cmd,title,plg,func,start=0,button=0) {
|
||||
// start = 0 : run command only when not already running (default)
|
||||
// start = 1 : run command unconditionally
|
||||
@@ -372,6 +384,7 @@ function openVMAction(cmd,title,plg,func,start=0,button=0) {
|
||||
$('button.confirm').prop('disabled',button==0);
|
||||
});
|
||||
}
|
||||
|
||||
function abortOperation(pid) {
|
||||
swal({title:"<?=_('Abort background operation')?>",text:"<?=_('This may leave an unknown state')?>",html:true,animation:'none',type:'warning',showCancelButton:true,confirmButtonText:"<?=_('Proceed')?>",cancelButtonText:"<?=_('Cancel')?>"},function(){
|
||||
$.post('/webGui/include/StartCommand.php',{kill:pid},function() {
|
||||
@@ -385,6 +398,7 @@ function abortOperation(pid) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function openChanges(cmd,title,nchan,button=0) {
|
||||
$('div.spinner.fixed').show();
|
||||
// button = 0 : hide CLOSE button (default)
|
||||
@@ -401,6 +415,7 @@ function openChanges(cmd,title,nchan,button=0) {
|
||||
$('button.confirm').text("<?=_('Done')?>").prop('disabled',false).show();
|
||||
});
|
||||
}
|
||||
|
||||
function openAlert(cmd,title,func) {
|
||||
$.post('/webGui/include/StartCommand.php',{cmd:cmd,start:2},function(data) {
|
||||
$('div.spinner.fixed').hide();
|
||||
@@ -411,6 +426,7 @@ function openAlert(cmd,title,func) {
|
||||
$('pre#swalbody').html(data);
|
||||
});
|
||||
}
|
||||
|
||||
function openDone(data) {
|
||||
if (data == '_DONE_') {
|
||||
$('div.spinner.fixed').hide();
|
||||
@@ -425,6 +441,7 @@ function openDone(data) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function openError(data) {
|
||||
if (data == '_ERROR_') {
|
||||
$('div.spinner.fixed').hide();
|
||||
@@ -433,16 +450,20 @@ function openError(data) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function showStatus(name,plugin,job) {
|
||||
$.post('/webGui/include/ProcessStatus.php',{name:name,plugin:plugin,job:job},function(status){$(".tabs").append(status);});
|
||||
}
|
||||
|
||||
function showFooter(data, id) {
|
||||
if (id !== undefined) $('#'+id).remove();
|
||||
$('#copyright').prepend(data);
|
||||
}
|
||||
|
||||
function showNotice(data) {
|
||||
$('#user-notice').html(data.replace(/<a>(.*)<\/a>/,"<a href='/Plugins'>$1</a>"));
|
||||
}
|
||||
|
||||
function escapeQuotes(form) {
|
||||
$(form).find('input[type=text]').each(function(){$(this).val($(this).val().replace(/"/g,'\\"'));});
|
||||
}
|
||||
@@ -520,12 +541,14 @@ function removeRebootNotice(message="<?=_('You must reboot for changes to take e
|
||||
function showUpgradeChanges() { /** @note can likely be removed, not used in webgui or api repos */
|
||||
openChanges("showchanges /tmp/plugins/unRAIDServer.txt","<?=_('Release Notes')?>");
|
||||
}
|
||||
|
||||
function showUpgrade(text,noDismiss=false) { /** @note can likely be removed, not used in webgui or api repos */
|
||||
if ($.cookie('os_upgrade')==null) {
|
||||
if (osUpgradeWarning) removeBannerWarning(osUpgradeWarning);
|
||||
osUpgradeWarning = addBannerWarning(text.replace(/<a>(.+?)<\/a>/,"<a href='#' onclick='openUpgrade()'>$1</a>").replace(/<b>(.*)<\/b>/,"<a href='#' onclick='document.rebootNow.submit()'>$1</a>"),false,noDismiss);
|
||||
}
|
||||
}
|
||||
|
||||
function hideUpgrade(set) { /** @note can likely be removed, not used in webgui or api repos */
|
||||
removeBannerWarning(osUpgradeWarning);
|
||||
if (set)
|
||||
@@ -533,6 +556,7 @@ function hideUpgrade(set) { /** @note can likely be removed, not used in webgui
|
||||
else
|
||||
$.removeCookie('os_upgrade');
|
||||
}
|
||||
|
||||
function confirmUpgrade(confirm) {
|
||||
if (confirm) {
|
||||
swal({title:"<?=_('Update')?> Unraid OS",text:"<?=_('Do you want to update to the new version')?>?",type:'warning',html:true,animation:'none',showCancelButton:true,closeOnConfirm:false,confirmButtonText:"<?=_('Proceed')?>",cancelButtonText:"<?=_('Cancel')?>"},function(){
|
||||
@@ -542,6 +566,7 @@ function confirmUpgrade(confirm) {
|
||||
openPlugin("plugin update unRAIDServer.plg","<?=_('Update')?> Unraid OS");
|
||||
}
|
||||
}
|
||||
|
||||
function openUpgrade() {
|
||||
hideUpgrade();
|
||||
$.get('/plugins/dynamix.plugin.manager/include/ShowPlugins.php',{cmd:'alert'},function(data) {
|
||||
@@ -554,11 +579,13 @@ function openUpgrade() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function digits(number) {
|
||||
if (number < 10) return 'one';
|
||||
if (number < 100) return 'two';
|
||||
return 'three';
|
||||
}
|
||||
|
||||
function openNotifier() {
|
||||
$.post('/webGui/include/Notify.php',{cmd:'get',csrf_token:csrf_token},function(msg) {
|
||||
$.each($.parseJSON(msg), function(i, notify){
|
||||
@@ -575,6 +602,7 @@ function openNotifier() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function closeNotifier() {
|
||||
$.post('/webGui/include/Notify.php',{cmd:'get',csrf_token:csrf_token},function(msg) {
|
||||
$.each($.parseJSON(msg), function(i, notify){
|
||||
@@ -583,14 +611,17 @@ function closeNotifier() {
|
||||
$('div.jGrowl').find('div.jGrowl-close').trigger('click');
|
||||
});
|
||||
}
|
||||
|
||||
function viewHistory() {
|
||||
location.replace('/Tools/NotificationsArchive');
|
||||
}
|
||||
|
||||
function flashReport() {
|
||||
$.post('/webGui/include/Report.php',{cmd:'config'},function(check){
|
||||
if (check>0) addBannerWarning("<?=_('Your flash drive is corrupted or offline').'. '._('Post your diagnostics in the forum for help').'.'?> <a target='_blank' href='https://docs.unraid.net/go/changing-the-flash-device/'><?=_('See also here')?></a>");
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
let tab;
|
||||
<?switch ($myPage['name']):?>
|
||||
@@ -867,7 +898,7 @@ function parseINI(msg) {
|
||||
// unraid animated logo
|
||||
var unraid_logo = '<?readfile("$docroot/webGui/images/animated-logo.svg")?>';
|
||||
|
||||
var defaultPage = new NchanSubscriber('/sub/session,var<?=$entity?",notify":""?>',{subscriber:'websocket'});
|
||||
var defaultPage = new NchanSubscriber('/sub/session,var<?=$entity?",notify":""?>',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
defaultPage.on('message', function(msg,meta) {
|
||||
switch (meta.id.channel()) {
|
||||
case 0:
|
||||
@@ -936,7 +967,7 @@ function wlanSettings() {
|
||||
window.location = '/Settings/NetworkSettings';
|
||||
}
|
||||
|
||||
var nchan_wlan0 = new NchanSubscriber('/sub/wlan0',{subscriber:'websocket'});
|
||||
var nchan_wlan0 = new NchanSubscriber('/sub/wlan0',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
nchan_wlan0.on('message', function(msg) {
|
||||
var wlan = JSON.parse(msg);
|
||||
$('#wlan0').removeClass().addClass(wlan.color).attr('title',wlan.title);
|
||||
@@ -944,7 +975,7 @@ nchan_wlan0.on('message', function(msg) {
|
||||
nchan_wlan0.start();
|
||||
<?endif;?>
|
||||
|
||||
var nchan_plugins = new NchanSubscriber('/sub/plugins',{subscriber:'websocket'});
|
||||
var nchan_plugins = new NchanSubscriber('/sub/plugins',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
nchan_plugins.on('message', function(data) {
|
||||
if (!data || openDone(data)) return;
|
||||
var box = $('pre#swaltext');
|
||||
@@ -957,7 +988,7 @@ nchan_plugins.on('message', function(data) {
|
||||
box.html(text.join('<br>')).scrollTop(box[0].scrollHeight);
|
||||
});
|
||||
|
||||
var nchan_docker = new NchanSubscriber('/sub/docker',{subscriber:'websocket'});
|
||||
var nchan_docker = new NchanSubscriber('/sub/docker',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
nchan_docker.on('message', function(data) {
|
||||
if (!data || openDone(data)) return;
|
||||
var box = $('pre#swaltext');
|
||||
@@ -1006,7 +1037,7 @@ nchan_docker.on('message', function(data) {
|
||||
box.scrollTop(box[0].scrollHeight);
|
||||
});
|
||||
|
||||
var nchan_vmaction = new NchanSubscriber('/sub/vmaction',{subscriber:'websocket'});
|
||||
var nchan_vmaction = new NchanSubscriber('/sub/vmaction',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
nchan_vmaction.on('message', function(data) {
|
||||
if (!data || openDone(data) || openError(data)) return;
|
||||
var box = $('pre#swaltext');
|
||||
@@ -1235,76 +1266,6 @@ $('body').on('click','a,.ca_href', function(e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Start & stop live updates when window loses focus
|
||||
var nchanPaused = false;
|
||||
var blurTimer = false;
|
||||
|
||||
$(window).focus(function() {
|
||||
nchanFocusStart();
|
||||
});
|
||||
|
||||
// Stop nchan on loss of focus
|
||||
<? if ( $display['liveUpdate'] == "no" ):?>
|
||||
$(window).blur(function() {
|
||||
blurTimer = setTimeout(function(){
|
||||
nchanFocusStop();
|
||||
},30000);
|
||||
});
|
||||
<?endif;?>
|
||||
|
||||
document.addEventListener("visibilitychange", (event) => {
|
||||
<? if ( $display['liveUpdate'] == "no" ):?>
|
||||
if (document.hidden) {
|
||||
nchanFocusStop();
|
||||
}
|
||||
<?else:?>
|
||||
if (document.hidden) {
|
||||
nchanFocusStop();
|
||||
} else {
|
||||
nchanFocusStart();
|
||||
}
|
||||
<?endif;?>
|
||||
});
|
||||
|
||||
function nchanFocusStart() {
|
||||
if ( blurTimer !== false ) {
|
||||
clearTimeout(blurTimer);
|
||||
blurTimer = false;
|
||||
}
|
||||
|
||||
if (nchanPaused !== false ) {
|
||||
removeBannerWarning(nchanPaused);
|
||||
nchanPaused = false;
|
||||
|
||||
try {
|
||||
pageFocusFunction();
|
||||
} catch(error) {}
|
||||
|
||||
subscribers.forEach(function(e) {
|
||||
e.start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function nchanFocusStop(banner=true) {
|
||||
if ( subscribers.length ) {
|
||||
if ( nchanPaused === false ) {
|
||||
var newsub = subscribers;
|
||||
subscribers.forEach(function(e) {
|
||||
try {
|
||||
e.stop();
|
||||
} catch(err) {
|
||||
newsub.splice(newsub.indexOf(e,1));
|
||||
}
|
||||
});
|
||||
subscribers = newsub;
|
||||
if ( banner && subscribers.length ) {
|
||||
nchanPaused = addBannerWarning("<?=_('Live Updates Paused');?>",false,true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user