diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index f3bbcab9..b5994b91 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -15,7 +15,6 @@
use OCA\FullTextSearch\Capabilities;
use OCA\FullTextSearch\ConfigLexicon;
use OCA\FullTextSearch\Search\UnifiedSearchProvider;
-use OCA\FullTextSearch\Service\ConfigService;
use OCA\FullTextSearch\Service\IndexService;
use OCA\FullTextSearch\Service\ProviderService;
use OCA\FullTextSearch\Service\SearchService;
@@ -32,28 +31,12 @@
use Psr\Container\ContainerInterface;
use Throwable;
-if (file_exists($autoLoad = __DIR__ . '/../../vendor/autoload.php')) {
- include_once $autoLoad;
-}
-
class Application extends App implements IBootstrap {
- const APP_ID = 'fulltextsearch';
- const APP_NAME = 'FullTextSearch';
-
-
- /**
- * Application constructor.
- *
- * @param array $params
- */
+ public const APP_ID = 'fulltextsearch';
public function __construct(array $params = []) {
parent::__construct(self::APP_ID, $params);
}
-
- /**
- * @param IRegistrationContext $context
- */
public function register(IRegistrationContext $context): void {
$context->registerCapability(Capabilities::class);
$context->registerSearchProvider(UnifiedSearchProvider::class);
diff --git a/lib/ConfigLexicon.php b/lib/ConfigLexicon.php
index 3e205e71..df348e06 100644
--- a/lib/ConfigLexicon.php
+++ b/lib/ConfigLexicon.php
@@ -26,6 +26,8 @@ class ConfigLexicon implements ILexicon {
public const COLLECTION_INDEXING_LIST = 'collection_indexing_list';
public const COLLECTION_INTERNAL = 'collection_internal';
public const COLLECTION_LINKS = 'collection_links';
+ public const LOCK_ID = 'lock_id';
+ public const LOCK_PING = 'lock_ping';
public function getStrictness(): Strictness {
return Strictness::NOTICE;
@@ -40,6 +42,9 @@ public function getAppConfigs(): array {
new Entry(key: self::COLLECTION_INDEXING_LIST, type: ValueType::INT, defaultRaw: 50, definition: 'size of chunks of async documents on collection queue request'),
new Entry(key: self::COLLECTION_INTERNAL, type: ValueType::STRING, defaultRaw: 'local', definition: 'name of the local collection'),
new Entry(key: self::COLLECTION_LINKS, type: ValueType::ARRAY, defaultRaw: [], definition: '(internal) data relative to collections'),
+ // IAppConfig::FLAG_INTERNAL)
+ new Entry(key: self::LOCK_ID, type: ValueType::STRING, defaultRaw: '', definition: 'internal lock id', lazy: true),
+ new Entry(key: self::LOCK_PING, type: ValueType::INT, defaultRaw: 0, definition: 'internal lock time', lazy: true),
];
}
diff --git a/lib/Db/TickRequest.php b/lib/Db/TickRequest.php
deleted file mode 100644
index 3563658c..00000000
--- a/lib/Db/TickRequest.php
+++ /dev/null
@@ -1,149 +0,0 @@
-getTickInsertSql();
- $qb->setValue('source', $qb->createNamedParameter($tick->getSource()))
- ->setValue('data', $qb->createNamedParameter(json_encode($tick->getData())))
- ->setValue('action', $qb->createNamedParameter($tick->getAction()))
- ->setValue('first_tick', $qb->createNamedParameter($tick->getFirstTick()))
- ->setValue('tick', $qb->createNamedParameter($tick->getTick()))
- ->setValue('status', $qb->createNamedParameter($tick->getStatus()));
-
- try {
- $qb->executeStatement();
- } catch (\OCP\DB\Exception $e) {
- if ($e->getReason() === \OCP\DB\Exception::REASON_CONNECTION_LOST) {
- $this->reconnect($e);
- return $this->create($tick);
- }
- throw $e;
- }
-
- return $qb->getLastInsertId();
- } catch (Exception $e) {
- throw $e;
- }
- }
-
- /**
- * @param Tick $tick
- *
- * @return bool
- */
- public function update(Tick $tick): bool {
- try {
- $this->getTickById($tick->getId());
- } catch (TickDoesNotExistException $e) {
- return false;
- }
-
- $qb = $this->getTickUpdateSql();
- $qb->set('data', $qb->createNamedParameter(json_encode($tick->getData())))
- ->set('tick', $qb->createNamedParameter($tick->getTick()))
- ->set('action', $qb->createNamedParameter($tick->getAction()))
- ->set('status', $qb->createNamedParameter($tick->getStatus()));
-
- $this->limitToId($qb, $tick->getId());
-
- try {
- $qb->executeStatement();
- } catch (\OCP\DB\Exception $e) {
- if ($e->getReason() === \OCP\DB\Exception::REASON_CONNECTION_LOST) {
- $this->reconnect($e);
- return $this->update($tick);
- }
- throw $e;
- }
-
- return true;
- }
-
- /**
- * return tick.
- *
- * @param int $id
- *
- * @return Tick
- * @throws TickDoesNotExistException
- */
- public function getTickById(int $id): Tick {
- $qb = $this->getTickSelectSql();
- $this->limitToId($qb, $id);
-
- try {
- $cursor = $qb->executeQuery();
- } catch (\OCP\DB\Exception $e) {
- if ($e->getReason() === \OCP\DB\Exception::REASON_CONNECTION_LOST) {
- $this->reconnect($e);
- return $this->getTickById($id);
- }
- throw $e;
- }
-
- $data = $cursor->fetch();
- $cursor->closeCursor();
-
- if ($data === false) {
- throw new TickDoesNotExistException($this->l10n->t('Process timed out'));
- }
-
- return $this->parseTickSelectSql($data);
- }
-
- /**
- * return ticks.
- *
- * @param string $status
- *
- * @return Tick[]
- */
- public function getTicksByStatus(string $status): array {
- $ticks = [];
-
- $qb = $this->getTickSelectSql();
- $this->limitToStatus($qb, $status);
-
- try {
- $cursor = $qb->executeQuery();
- } catch (\OCP\DB\Exception $e) {
- if ($e->getReason() === \OCP\DB\Exception::REASON_CONNECTION_LOST) {
- $this->reconnect($e);
- return $this->getTicksByStatus($status);
- }
- throw $e;
- }
-
- while ($data = $cursor->fetch()) {
- $ticks[] = $this->parseTickSelectSql($data);
- }
- $cursor->closeCursor();
-
- return $ticks;
- }
-}
diff --git a/lib/Db/TickRequestBuilder.php b/lib/Db/TickRequestBuilder.php
deleted file mode 100644
index f5a85bc6..00000000
--- a/lib/Db/TickRequestBuilder.php
+++ /dev/null
@@ -1,103 +0,0 @@
-dbConnection->getQueryBuilder();
- $qb->insert(self::TABLE_TICKS);
-
- return $qb;
- }
-
-
- /**
- * Base of the Sql Update request
- *
- * @return IQueryBuilder
- */
- protected function getTickUpdateSql(): IQueryBuilder {
- $qb = $this->dbConnection->getQueryBuilder();
- $qb->update(self::TABLE_TICKS);
-
- return $qb;
- }
-
-
- /**
- * Base of the Sql Select request for Shares
- *
- * @return IQueryBuilder
- */
- protected function getTickSelectSql(): IQueryBuilder {
- $qb = $this->dbConnection->getQueryBuilder();
-
- /** @noinspection PhpMethodParametersCountMismatchInspection */
- $qb->select(
- 't.id', 't.source', 't.data', 't.first_tick', 't.tick', 't.status', 't.action'
- )
- ->from(self::TABLE_TICKS, 't');
-
- $this->defaultSelectAlias = 't';
-
- return $qb;
- }
-
-
- /**
- * Base of the Sql Delete request
- *
- * @return IQueryBuilder
- */
- protected function getTickDeleteSql(): IQueryBuilder {
- $qb = $this->dbConnection->getQueryBuilder();
- $qb->delete(self::TABLE_TICKS);
-
- return $qb;
- }
-
-
- /**
- * @param array $data
- *
- * @return Tick
- */
- protected function parseTickSelectSql(array $data): Tick {
- $tick = new Tick($this->get('source', $data, ''), $this->getInt('id', $data, 0));
- $tick->setData($this->getArray('data', $data, []))
- ->setTick($this->getInt('tick', $data, 0))
- ->setFirstTick($this->getInt('first_tick', $data, 0))
- ->setStatus($this->get('status', $data, ''))
- ->setAction($this->get('action', $data, ''));
-
- return $tick;
- }
-
-}
diff --git a/lib/Exceptions/LockException.php b/lib/Exceptions/LockException.php
new file mode 100644
index 00000000..3a965fbb
--- /dev/null
+++ b/lib/Exceptions/LockException.php
@@ -0,0 +1,14 @@
+hasTable('fulltextsearch_ticks')) {
+ return null;
+ }
+
+ $schema->dropTable('fulltextsearch_ticks');
+ return $schema;
+ }
+}
diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php
index d23fd40d..7dcfa7c9 100644
--- a/lib/Service/ConfigService.php
+++ b/lib/Service/ConfigService.php
@@ -16,7 +16,6 @@
class ConfigService {
public function __construct(
private readonly IAppConfig $appConfig,
- private readonly IConfig $config,
) {
}
@@ -57,12 +56,6 @@ public function setConfig(array $save): void {
}
}
- public function getAppValue(string $key): string {
- return $this->config->getSystemValueString(Application::APP_ID . '.' . $key,
- (string)$this->appConfig->getAppValueString($key)
- );
- }
-
public function getInternalCollection(): string {
return $this->appConfig->getAppValueString(ConfigLexicon::COLLECTION_INTERNAL);
}
diff --git a/lib/Service/LockService.php b/lib/Service/LockService.php
new file mode 100644
index 00000000..cfb5656a
--- /dev/null
+++ b/lib/Service/LockService.php
@@ -0,0 +1,99 @@
+lockId = $random->generate(7);
+ }
+
+ /**
+ * Lock the index to this process for few minutes.
+ * Needs to be refreshed to keep lock alive.
+ *
+ * _**Warning:** reload lazy app config._
+ *
+ * @throws LockException if the index is already running
+ */
+ public function lock(): void {
+ $this->appConfig->clearCache(true);
+ $currentLockPing = $this->appConfig->getValueInt(Application::APP_ID, ConfigLexicon::LOCK_PING);
+ $currentLockId = $this->appConfig->getValueString(Application::APP_ID, ConfigLexicon::LOCK_ID);
+
+ // previous lock timeout
+ if ($currentLockPing < time()) {
+ $currentLockId = '';
+ }
+
+ // new lock; enforce ping on new lock
+ if ($currentLockId === '') {
+ $this->appConfig->setValueString(Application::APP_ID, ConfigLexicon::LOCK_ID, $this->lockId);
+ $currentLockId = $this->lockId;
+ $this->nextPing = 0;
+ }
+
+ // confirm the lock belongs to the current process
+ if ($currentLockId !== $this->lockId) {
+ throw new LockException('Index is already running');
+ }
+
+ $this->update();
+ }
+
+ public function update(): void {
+ if ($this->nextPing === -1) {
+ throw new LockException('Lock service not initiated on this process');
+ }
+
+ $time = time();
+
+ // do not flood database
+ if ($this->nextPing > $time) {
+ return;
+ }
+
+ $this->appConfig->clearCache(true);
+ $currentLockId = $this->appConfig->getValueString(Application::APP_ID, ConfigLexicon::LOCK_ID);
+
+ // new lock; enforce ping on new lock
+ if ($currentLockId === '') {
+ throw new LockException('Index not locked');
+ }
+
+ // confirm the lock belongs to the current process
+ if ($currentLockId !== $this->lockId) {
+ throw new LockException('Index locked by another process');
+ }
+
+ // update ping
+ $this->nextPing = $time + self::LOCK_PING_DELAY;
+ $this->appConfig->setValueInt(Application::APP_ID, ConfigLexicon::LOCK_PING, $this->nextPing + self::LOCK_TIMEOUT);
+ }
+
+ public function unlock(): void {
+ $this->appConfig->deleteKey(Application::APP_ID, ConfigLexicon::LOCK_PING);
+ $this->nextPing = -1;
+ }
+}
diff --git a/lib/Service/RunningService.php b/lib/Service/RunningService.php
index a90c8530..8337d657 100644
--- a/lib/Service/RunningService.php
+++ b/lib/Service/RunningService.php
@@ -9,182 +9,46 @@
namespace OCA\FullTextSearch\Service;
-use Exception;
-use OCA\FullTextSearch\ConfigLexicon;
-use OCA\FullTextSearch\Db\TickRequest;
+use OCA\FullTextSearch\Exceptions\LockException;
use OCA\FullTextSearch\Exceptions\RunnerAlreadyUpException;
-use OCA\FullTextSearch\Exceptions\TickDoesNotExistException;
-use OCA\FullTextSearch\Exceptions\TickIsNotAliveException;
-use OCA\FullTextSearch\Model\Tick;
-use OCP\AppFramework\Services\IAppConfig;
+/**
+ * @deprecated
+ * @see LockService
+ */
class RunningService {
public function __construct(
- private TickRequest $tickRequest,
- private readonly IAppConfig $appConfig,
+ private readonly LockService $lockService,
) {
}
/**
- * @param string $source
- *
- * @return int
- * @throws RunnerAlreadyUpException
- * @throws Exception
+ * @deprecated
*/
public function start(string $source): int {
-
- if ($this->isAlreadyRunning()) {
- throw new RunnerAlreadyUpException('Index is already running');
+ try {
+ $this->lockService->lock();
+ } catch (LockException $e) {
+ throw new RunnerAlreadyUpException($e->getMessage());
}
-
- $tick = new Tick($source);
- $tick->setStatus('run')
- ->setTick()
- ->setFirstTick()
- ->setInfoInt('runStart ', time());
-
- return $this->tickRequest->create($tick);
+ return 1;
}
-
/**
- * @param int $runId
- * @param string $action
- *
- * @throws TickDoesNotExistException
- * @throws TickIsNotAliveException
+ * @deprecated
*/
public function update(int $runId, string $action = '') {
- $tick = $this->tickRequest->getTickById($runId);
-
- $this->isStillAlive($tick, true);
- $tick->setTick();
-
- if ($action !== '' && $action !== $tick->getAction()) {
- $this->assignActionToTick($tick, $action);
- }
-
- $this->tickRequest->update($tick);
- }
-
-
- /**
- * @param int $runId
- * @param string $reason
- *
- * @throws TickDoesNotExistException
- */
- public function stop(int $runId, string $reason = '') {
- $tick = $this->tickRequest->getTickById($runId);
- $tick->setStatus('stop')
- ->setTick()
- ->setInfoInt('runStop', time())
- ->setInfoInt('totalDocuments', 42);
-
- if ($reason !== '') {
- $tick->setStatus('exception');
- $tick->setInfo('exception', $reason);
- }
-
- $this->tickRequest->update($tick);
- }
-
-
- /**
- * @param int $runId
- *
- * @return bool
- * @throws TickIsNotAliveException
- */
- public function isAlive(int $runId): bool {
- $tick = null;
try {
- $tick = $this->tickRequest->getTickById($runId);
- } catch (TickDoesNotExistException $e) {
- return false;
- }
-
- return $this->isStillAlive($tick);
- }
-
-
- /**
- * @param Tick $tick
- * @param bool $exception
- *
- * @return bool
- * @throws TickIsNotAliveException
- */
- public function isStillAlive(Tick $tick, bool $exception = false): bool {
- if ($tick->getStatus() !== 'run') {
- if ($exception) {
- throw new TickIsNotAliveException();
- } else {
- return false;
- }
- }
-
- return true;
- }
-
-
- /**
- * @return bool
- */
- public function isAlreadyRunning(): bool {
- $ttl = $this->appConfig->getAppValueInt(ConfigLexicon::TICK_TTL);
- $ticks = $this->tickRequest->getTicksByStatus('run');
-
- $isAlreadyRunning = false;
- foreach ($ticks as $tick) {
- if ($tick->getTick() < (time() - $ttl)) {
- $tick->setStatus('timeout');
- $this->tickRequest->update($tick);
- } else {
- $isAlreadyRunning = true;
- }
- }
-
- return $isAlreadyRunning;
- }
-
-
- /**
- *
- */
- public function forceStop() {
- $ticks = $this->tickRequest->getTicksByStatus('run');
-
- foreach ($ticks as $tick) {
- $tick->setStatus('forceStop');
- $this->tickRequest->update($tick);
+ $this->lockService->update();
+ } catch (LockException $e) {
+ throw new RunnerAlreadyUpException($e->getMessage());
}
}
-
/**
- * @param Tick $tick
- * @param string $action
+ * @deprecated
*/
- private function assignActionToTick(Tick $tick, string $action) {
- $now = microtime(true);
- $preAction = $tick->getAction();
-
- if ($preAction !== '') {
- $preActionTotal = $tick->getInfoFloat($preAction . 'Total', 0);
- $preActionStart = $tick->getInfoFloat($preAction . 'Init', 0);
-
- if ($preActionStart > 0) {
-
- $preActionTotal += ($now - $preActionStart);
- $tick->setInfoFloat($preAction . 'Total', $preActionTotal);
- $tick->unsetInfo($preAction . 'Init');
- }
- }
- $tick->setAction($action)
- ->setInfoFloat($action . 'Init', $now);
+ public function stop(int $runId, string $reason = '') {
+ $this->lockService->unlock();
}
-
-
}
diff --git a/screenshots/0.3.0.png b/screenshots/0.3.0.png
deleted file mode 100644
index 93b41074..00000000
Binary files a/screenshots/0.3.0.png and /dev/null differ
diff --git a/screenshots/OccFulltextsearchIndex.png b/screenshots/OccFulltextsearchIndex.png
deleted file mode 100644
index 3ed16dc6..00000000
Binary files a/screenshots/OccFulltextsearchIndex.png and /dev/null differ
diff --git a/screenshots/OccFulltextsearchTest.png b/screenshots/OccFulltextsearchTest.png
deleted file mode 100644
index c3091bd9..00000000
Binary files a/screenshots/OccFulltextsearchTest.png and /dev/null differ
diff --git a/screenshots/SchemaIndexCommand.jpg b/screenshots/SchemaIndexCommand.jpg
deleted file mode 100644
index a7b29140..00000000
Binary files a/screenshots/SchemaIndexCommand.jpg and /dev/null differ
diff --git a/screenshots/SchemaIndexLive.jpg b/screenshots/SchemaIndexLive.jpg
deleted file mode 100644
index 066b6aff..00000000
Binary files a/screenshots/SchemaIndexLive.jpg and /dev/null differ
diff --git a/screenshots/SchemaSearch.jpg b/screenshots/SchemaSearch.jpg
deleted file mode 100644
index 0a0a51cc..00000000
Binary files a/screenshots/SchemaSearch.jpg and /dev/null differ
diff --git a/screenshots/configuration.png b/screenshots/configuration.png
deleted file mode 100644
index 94289796..00000000
Binary files a/screenshots/configuration.png and /dev/null differ
diff --git a/screenshots/draw.io/Index.xml b/screenshots/draw.io/Index.xml
deleted file mode 100644
index 79b8005c..00000000
--- a/screenshots/draw.io/Index.xml
+++ /dev/null
@@ -1 +0,0 @@
-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
\ No newline at end of file
diff --git a/screenshots/draw.io/Search.xml b/screenshots/draw.io/Search.xml
deleted file mode 100644
index 3dd4eca6..00000000
--- a/screenshots/draw.io/Search.xml
+++ /dev/null
@@ -1 +0,0 @@
-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
\ No newline at end of file