| @@ -1,11 +1,14 @@ | |||||||
| package envoy.client.data; | package envoy.client.data; | ||||||
|  |  | ||||||
| import java.io.*; | import java.io.*; | ||||||
|  | import java.nio.channels.*; | ||||||
|  | import java.nio.file.StandardOpenOption; | ||||||
| import java.time.Instant; | import java.time.Instant; | ||||||
| import java.util.*; | import java.util.*; | ||||||
|  |  | ||||||
| import envoy.data.*; | import envoy.data.*; | ||||||
| import envoy.event.*; | import envoy.event.*; | ||||||
|  | import envoy.exception.EnvoyException; | ||||||
| import envoy.util.SerializationUtils; | import envoy.util.SerializationUtils; | ||||||
|  |  | ||||||
| import dev.kske.eventbus.Event; | import dev.kske.eventbus.Event; | ||||||
| @@ -35,6 +38,7 @@ public final class LocalDB implements EventListener { | |||||||
| 	private Instant				lastSync	= Instant.EPOCH; | 	private Instant				lastSync	= Instant.EPOCH; | ||||||
| 	private String				authToken; | 	private String				authToken; | ||||||
| 	private File				dbDir, userFile, idGeneratorFile, lastLoginFile, usersFile; | 	private File				dbDir, userFile, idGeneratorFile, lastLoginFile, usersFile; | ||||||
|  | 	private FileLock			instanceLock; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Constructs an empty local database. To serialize any user-specific data to | 	 * 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"); | 		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 | 	 * 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. | 	 * 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 | 		// Initialize the local database | ||||||
| 		try { | 		try { | ||||||
| 			localDB = new LocalDB(new File(config.getHomeDirectory(), config.getLocalDB().getPath())); | 			File localDBDir = new File(config.getHomeDirectory(), config.getLocalDB().getPath()); | ||||||
| 		} catch (final IOException e3) { | 			logger.info("Initializing LocalDB at " + localDBDir); | ||||||
| 			logger.log(Level.SEVERE, "Could not initialize local database: ", e3); | 			localDB = new LocalDB(localDBDir); | ||||||
| 			new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e3).showAndWait(); | 			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); | 			System.exit(1); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user