Created
August 4, 2015 02:25
-
-
Save aackerman/d490e348e2ff1d610ff7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var net = require('net'); | |
| var fs = require('fs'); | |
| var os = require('os'); | |
| var path = require('path'); | |
| var osExtras = require('./os_extras'); | |
| let defaultOptions = { | |
| name: 'Application', | |
| socketPath: 'application' | |
| }; | |
| function getDefaultSocket() { | |
| let pipeName = `application-${process.env.USER}-sock`; | |
| let tmpName = `application-${process.env.USER}.sock`; | |
| return osExtras.isWindows() ? `\\\\.\\pipe\\${pipeName}` : path.join(os.tmpdir(), tmpName); | |
| } | |
| function deleteSocketFile(socketPath) { | |
| // no need to delete the socket file on windows, pipes are cleaned up | |
| if ( osExtras.isWindows() ) { return; } | |
| if ( fs.existsSync(socketPath) ) { | |
| try { | |
| fs.unlinkSync(socketPath); | |
| } catch (error) { | |
| // Ignore ENOENT errors in case the file was deleted between the exists | |
| // check and the call to unlink sync. | |
| if (error.code != 'ENOENT') { | |
| // rethrow the error | |
| throw error; | |
| } | |
| } | |
| } | |
| } | |
| // Create server to listen for additional application launches | |
| function listenForNewProcesses(socketPath) { | |
| // delete any current socket paths | |
| deleteSocketFile(socketPath); | |
| // create a server for listening on the socket path | |
| var server = net.createServer(function(connection) { | |
| connection.on('data', function(data) { | |
| console.log('Another instance of the application was launched and will terminate'); | |
| }); | |
| }); | |
| // listen on the socket path to allow other instance to know to terminate | |
| server.listen(socketPath); | |
| // log errors | |
| server.on('error', function(error) { | |
| console.error('Application server failed', error); | |
| }); | |
| } | |
| class Application { | |
| constructor(options = {}) { | |
| // listen for new processes to connect so they can know | |
| // to terminate themselves because an instance is already running | |
| listenForNewProcesses(options.socketPath); | |
| } | |
| getName() { | |
| return this.name; | |
| } | |
| } | |
| export default (options = {}) => { | |
| options = Object.assign({}, defaultOptions, options); | |
| var app = require('app'); | |
| // application callback | |
| function createApplication() { | |
| return new Application(options); | |
| } | |
| // if the socket doesn't exist or the platform is windows | |
| // attempt to connect to determine if another instance is running | |
| if ( osExtras.isWindows() || fs.existsSync(socketPath) ) { | |
| // attempt to connect on the socket path and if we can | |
| // terminate the application, an instance is already running | |
| var client = net.connect({ path: socketPath }, function(){ | |
| // write to the socket and terminate | |
| client.write('{}', function() { | |
| client.end(); | |
| app.terminate(); | |
| }); | |
| }); | |
| // continue with application startup if the client errors | |
| client.on('error', createApplication); | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment