| @@ -1,11 +1,14 @@ | ||||
| package envoy.client.data; | ||||
|  | ||||
| import java.io.*; | ||||
| import java.nio.channels.*; | ||||
| import java.nio.file.StandardOpenOption; | ||||
| import java.time.Instant; | ||||
| import java.util.*; | ||||
|  | ||||
| import envoy.data.*; | ||||
| import envoy.event.*; | ||||
| import envoy.exception.EnvoyException; | ||||
| import envoy.util.SerializationUtils; | ||||
|  | ||||
| import dev.kske.eventbus.Event; | ||||
| @@ -35,6 +38,7 @@ public final class LocalDB implements EventListener { | ||||
| 	private Instant				lastSync	= Instant.EPOCH; | ||||
| 	private String				authToken; | ||||
| 	private File				dbDir, userFile, idGeneratorFile, lastLoginFile, usersFile; | ||||
| 	private FileLock			instanceLock; | ||||
|  | ||||
| 	/** | ||||
| 	 * Constructs an empty local database. To serialize any user-specific data to | ||||
| @@ -74,6 +78,28 @@ public final class LocalDB implements EventListener { | ||||
| 		userFile = new File(dbDir, user.getID() + ".db"); | ||||
| 	} | ||||
|  | ||||
| 	FileChannel fc; | ||||
|  | ||||
| 	/** | ||||
| 	 * Ensured that only one Envoy instance is using this local database by creating | ||||
| 	 * a lock file. | ||||
| 	 * The lock file is deleted on application exit. | ||||
| 	 * | ||||
| 	 * @throws EnvoyException if the lock cannot by acquired | ||||
| 	 * @since Envoy Client v0.2-beta | ||||
| 	 */ | ||||
| 	public void lock() throws EnvoyException { | ||||
| 		File file = new File(dbDir, "instance.lock"); | ||||
| 		file.deleteOnExit(); | ||||
| 		try { | ||||
| 			FileChannel fc = FileChannel.open(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE); | ||||
| 			instanceLock = fc.tryLock(); | ||||
| 			if (instanceLock == null) throw new EnvoyException("Another Envoy instance is using this local database!"); | ||||
| 		} catch (IOException e) { | ||||
| 			throw new EnvoyException("Could not create lock file!", e); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Stores all users. If the client user is specified, their chats will be stored | ||||
| 	 * as well. The message id generator will also be saved if present. | ||||
|   | ||||
| @@ -67,10 +67,13 @@ public final class Startup extends Application { | ||||
|  | ||||
| 		// Initialize the local database | ||||
| 		try { | ||||
| 			localDB = new LocalDB(new File(config.getHomeDirectory(), config.getLocalDB().getPath())); | ||||
| 		} catch (final IOException e3) { | ||||
| 			logger.log(Level.SEVERE, "Could not initialize local database: ", e3); | ||||
| 			new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e3).showAndWait(); | ||||
| 			File localDBDir = new File(config.getHomeDirectory(), config.getLocalDB().getPath()); | ||||
| 			logger.info("Initializing LocalDB at " + localDBDir); | ||||
| 			localDB = new LocalDB(localDBDir); | ||||
| 			localDB.lock(); | ||||
| 		} catch (IOException | EnvoyException e) { | ||||
| 			logger.log(Level.SEVERE, "Could not initialize local database: ", e); | ||||
| 			new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e).showAndWait(); | ||||
| 			System.exit(1); | ||||
| 			return; | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user