mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-31 00:11:59 +02:00
Add Clapper deamon subprocess
Daemon is responsible for starting and later watching over spawned "broadwayd" and "remote" app needed for remote playback control. We cannot use systemd n Flatpak, so we make do with running optional background subprocesses.
This commit is contained in:
@@ -3,15 +3,15 @@
|
|||||||
/* pkg init enforces the imports path to the folder
|
/* pkg init enforces the imports path to the folder
|
||||||
* named after the pkg name, but I would prefer to have
|
* named after the pkg name, but I would prefer to have
|
||||||
* the bundled subprocess stored in the same directory */
|
* the bundled subprocess stored in the same directory */
|
||||||
imports.searchPath.unshift('@datadir@/@PROJECT_NAME@');
|
imports.searchPath.unshift('@datadir@/@PACKAGE_NAME@');
|
||||||
|
|
||||||
const Package = imports.package;
|
const Package = imports.package;
|
||||||
|
|
||||||
Package.init({
|
Package.init({
|
||||||
name: '@PACKAGE_NAME@',
|
name: '@PACKAGE_NAME@.@ID_POSTFIX@',
|
||||||
version: '@PACKAGE_VERSION@',
|
version: '@PACKAGE_VERSION@',
|
||||||
prefix: '@prefix@',
|
prefix: '@prefix@',
|
||||||
libdir: '@libdir@',
|
libdir: '@libdir@',
|
||||||
datadir: '@datadir@',
|
datadir: '@datadir@',
|
||||||
});
|
});
|
||||||
Package.run(imports.clapper_src.mainRemote);
|
Package.run(imports.clapper_src.main@ID_POSTFIX@);
|
@@ -1,18 +1,21 @@
|
|||||||
clapper_apps = [ '', '.Remote' ]
|
clapper_apps = ['', 'Remote', 'Daemon']
|
||||||
|
|
||||||
foreach id_postfix : clapper_apps
|
foreach id_postfix : clapper_apps
|
||||||
|
app_postfix = (id_postfix != '') ? '.' + id_postfix : ''
|
||||||
|
template_type = (id_postfix != '') ? '.Subprocess' : ''
|
||||||
|
|
||||||
bin_conf = configuration_data()
|
bin_conf = configuration_data()
|
||||||
bin_conf.set('GJS', find_program('gjs').path())
|
bin_conf.set('GJS', find_program('gjs').path())
|
||||||
bin_conf.set('PROJECT_NAME', meson.project_name())
|
bin_conf.set('PACKAGE_NAME', meson.project_name())
|
||||||
bin_conf.set('PACKAGE_NAME', meson.project_name() + id_postfix)
|
|
||||||
bin_conf.set('PACKAGE_VERSION', meson.project_version())
|
bin_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||||
|
bin_conf.set('ID_POSTFIX', id_postfix)
|
||||||
bin_conf.set('prefix', get_option('prefix'))
|
bin_conf.set('prefix', get_option('prefix'))
|
||||||
bin_conf.set('libdir', join_paths(get_option('prefix'), get_option('libdir')))
|
bin_conf.set('libdir', join_paths(get_option('prefix'), get_option('libdir')))
|
||||||
bin_conf.set('datadir', join_paths(get_option('prefix'), get_option('datadir')))
|
bin_conf.set('datadir', join_paths(get_option('prefix'), get_option('datadir')))
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
input: 'com.github.rafostar.Clapper' + id_postfix + '.in',
|
input: 'com.github.rafostar.Clapper' + template_type + '.in',
|
||||||
output: 'com.github.rafostar.Clapper' + id_postfix,
|
output: 'com.github.rafostar.Clapper' + app_postfix,
|
||||||
configuration: bin_conf,
|
configuration: bin_conf,
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: get_option('bindir'),
|
install_dir: get_option('bindir'),
|
||||||
|
66
clapper_src/daemon.js
Normal file
66
clapper_src/daemon.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
const { Gio, GLib, GObject } = imports.gi;
|
||||||
|
const Debug = imports.clapper_src.debug;
|
||||||
|
|
||||||
|
let { debug } = Debug;
|
||||||
|
|
||||||
|
var Daemon = GObject.registerClass(
|
||||||
|
class ClapperDaemon extends Gio.SubprocessLauncher
|
||||||
|
{
|
||||||
|
_init()
|
||||||
|
{
|
||||||
|
/* FIXME: show output when debugging is on */
|
||||||
|
const flags = Gio.SubprocessFlags.STDOUT_SILENCE
|
||||||
|
| Gio.SubprocessFlags.STDERR_SILENCE;
|
||||||
|
|
||||||
|
super._init({ flags });
|
||||||
|
|
||||||
|
this.errMsg = 'exited with error or was forced to close';
|
||||||
|
this.loop = GLib.MainLoop.new(null, false);
|
||||||
|
|
||||||
|
this.broadwayd = this.spawnv(['gtk4-broadwayd', '--port=8086']);
|
||||||
|
this.broadwayd.wait_async(null, this._onBroadwaydClosed.bind(this));
|
||||||
|
|
||||||
|
this.setenv('GDK_BACKEND', 'broadway', true);
|
||||||
|
|
||||||
|
const remoteApp = this.spawnv(['com.github.rafostar.Clapper.Remote']);
|
||||||
|
remoteApp.wait_async(null, this._onRemoteClosed.bind(this));
|
||||||
|
|
||||||
|
this.loop.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkProcResult(proc, result)
|
||||||
|
{
|
||||||
|
let hadError = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
hadError = proc.wait_finish(result);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
debug(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onBroadwaydClosed(proc, result)
|
||||||
|
{
|
||||||
|
const hadError = this._checkProcResult(proc, result);
|
||||||
|
|
||||||
|
if(hadError)
|
||||||
|
debug(`broadwayd ${this.errMsg}`);
|
||||||
|
|
||||||
|
this.broadwayd = null;
|
||||||
|
this.loop.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
_onRemoteClosed(proc, result)
|
||||||
|
{
|
||||||
|
const hadError = this._checkProcResult(proc, result);
|
||||||
|
|
||||||
|
if(hadError)
|
||||||
|
debug(`remote app ${this.errMsg}`);
|
||||||
|
|
||||||
|
if(this.broadwayd)
|
||||||
|
this.broadwayd.force_exit();
|
||||||
|
}
|
||||||
|
});
|
6
clapper_src/mainDaemon.js
Normal file
6
clapper_src/mainDaemon.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const { Daemon } = imports.clapper_src.daemon;
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
new Daemon();
|
||||||
|
}
|
@@ -296,13 +296,14 @@ class ClapperPlayerBase extends GstPlayer.Player
|
|||||||
if(!this.webapp)
|
if(!this.webapp)
|
||||||
this.webapp = new WebApp();
|
this.webapp = new WebApp();
|
||||||
|
|
||||||
this.webapp.startRemoteApp();
|
this.webapp.startDaemonApp();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this.webapp.stopRemoteApp();
|
this.webapp.stopDaemonApp();
|
||||||
}
|
}
|
||||||
else if(this.webserver) {
|
else if(this.webserver) {
|
||||||
/* remote app will close too when connection is lost */
|
/* remote app will close when connection is lost
|
||||||
|
* which will cause the daemon to close too */
|
||||||
this.webserver.stopListening();
|
this.webserver.stopListening();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -14,35 +14,33 @@ class ClapperWebApp extends Gio.SubprocessLauncher
|
|||||||
|
|
||||||
super._init({ flags });
|
super._init({ flags });
|
||||||
|
|
||||||
this.remoteApp = null;
|
this.daemonApp = null;
|
||||||
this.isRemoteClosing = false;
|
this.isDaemonClosing = false;
|
||||||
|
|
||||||
this.setenv('GDK_BACKEND', 'broadway', true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startRemoteApp()
|
startDaemonApp()
|
||||||
{
|
{
|
||||||
if(this.remoteApp)
|
if(this.daemonApp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.remoteApp = this.spawnv([Misc.appId + '.Remote']);
|
this.daemonApp = this.spawnv([Misc.appId + '.Daemon']);
|
||||||
this.remoteApp.wait_async(null, this._onRemoteClosed.bind(this));
|
this.daemonApp.wait_async(null, this._onDaemonClosed.bind(this));
|
||||||
|
|
||||||
debug('remote app started');
|
debug('daemon app started');
|
||||||
}
|
}
|
||||||
|
|
||||||
stopRemoteApp()
|
stopDaemonApp()
|
||||||
{
|
{
|
||||||
if(!this.remoteApp || this.isRemoteClosing)
|
if(!this.daemonApp || this.isDaemonClosing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.isRemoteClosing = true;
|
this.isDaemonClosing = true;
|
||||||
this.remoteApp.force_exit();
|
this.daemonApp.force_exit();
|
||||||
|
|
||||||
debug('send stop signal to remote app');
|
debug('send stop signal to daemon app');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRemoteClosed(proc, result)
|
_onDaemonClosed(proc, result)
|
||||||
{
|
{
|
||||||
let hadError;
|
let hadError;
|
||||||
|
|
||||||
@@ -53,12 +51,12 @@ class ClapperWebApp extends Gio.SubprocessLauncher
|
|||||||
debug(err);
|
debug(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.remoteApp = null;
|
this.daemonApp = null;
|
||||||
this.isRemoteClosing = false;
|
this.isDaemonClosing = false;
|
||||||
|
|
||||||
if(hadError)
|
if(hadError)
|
||||||
debug('remote app exited with error');
|
debug('daemon app exited with error or was forced to close');
|
||||||
|
|
||||||
debug('remote app closed');
|
debug('daemon app closed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user