diff --git a/.env b/.env
index 08c0e6eccb..f7d7d9247a 100644
--- a/.env
+++ b/.env
@@ -1,6 +1,6 @@
_APP_ENV=development
_APP_LOCALE=en
-_APP_WORKER_PER_CORE=6
+_APP_WORKER_PER_CORE=2
_APP_CONSOLE_WHITELIST_ROOT=disabled
_APP_CONSOLE_WHITELIST_EMAILS=
_APP_CONSOLE_WHITELIST_IPS=
@@ -24,7 +24,8 @@ _APP_DB_SCHEMA=appwrite
_APP_DB_USER=user
_APP_DB_PASS=password
_APP_DB_ROOT_PASS=rootsecretpassword
-_APP_CONNECTIONS_MAX=251
+_APP_CONNECTIONS_MAX=3100
+_APP_POOL_CLIENTS=14
_APP_CONNECTIONS_DB_PROJECT=db_fra1_02=mariadb://user:password@mariadb:3306/appwrite
_APP_CONNECTIONS_DB_CONSOLE=db_fra1_01=mariadb://user:password@mariadb:3306/appwrite
_APP_CONNECTIONS_CACHE=redis_fra1_01=redis://redis:6379
@@ -53,6 +54,7 @@ _APP_FUNCTIONS_BUILD_TIMEOUT=900
_APP_FUNCTIONS_CPUS=1
_APP_FUNCTIONS_MEMORY=512
_APP_FUNCTIONS_INACTIVE_THRESHOLD=600
+_APP_FUNCTIONS_MAINTENANCE_INTERVAL=600
_APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes
_APP_EXECUTOR_SECRET=your-secret-key
_APP_EXECUTOR_HOST=http://exc1/v1
@@ -63,9 +65,9 @@ _APP_MAINTENANCE_RETENTION_EXECUTION=1209600
_APP_MAINTENANCE_RETENTION_ABUSE=86400
_APP_MAINTENANCE_RETENTION_AUDIT=1209600
_APP_MAINTENANCE_RETENTION_SCHEDULES=86400
-_APP_USAGE_TIMESERIES_INTERVAL=20
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
_APP_USAGE_STATS=enabled
+_APP_USAGE_AGGREGATION_INTERVAL=30
_APP_LOGGING_PROVIDER=
_APP_LOGGING_CONFIG=
_APP_REGION=nyc1
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 8e185944b6..cff75b73b4 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -33,6 +33,7 @@ jobs:
docker compose build appwrite
docker compose up -d
sleep 30
+
- name: Doctor
run: docker compose exec -T appwrite doctor
diff --git a/.gitpod.yml b/.gitpod.yml
index a63c07bad2..4c081dd275 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -1,8 +1,9 @@
tasks:
- name: Run Appwrite Docker Stack
init: |
- docker compose pull
+ git submodule update --init
docker compose build
+ docker compose pull
docker pull composer
command: |
docker run --rm --interactive --tty \
diff --git a/CHANGES.md b/CHANGES.md
index 0780d6ea6e..7a553d5d5e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,11 +1,23 @@
# TBD
-
- Replace Appwrite executor with OpenRuntimes Executor [#4650](https://github.com/appwrite/appwrite/pull/4650)
- Add `_APP_CONNECTIONS_MAX` env var [#4673](https://github.com/appwrite/appwrite/pull/4673)
-- Update Traefik 2.7 -> 2.9 [#4673](https://github.com/appwrite/appwrite/pull/4673)
- Increase Traefik TCP + file limits [#4673](https://github.com/appwrite/appwrite/pull/4673)
-# Version 1.1.1
+- Fix invited account verified status [#4776](https://github.com/appwrite/appwrite/pull/4776)
+- Get default region from environment on project create [#4780](https://github.com/appwrite/appwrite/pull/4780)
+- Fix max mimetype size [#4814](https://github.com/appwrite/appwrite/pull/4814)
+# Version 1.1.2
+## Changes
+- Released `appwrite/console` [2.0.2](https://github.com/appwrite/console/releases/tag/2.0.2)
+- Make `region` parameter optional with default for project create [#4763](https://github.com/appwrite/appwrite/pull/4763)
+
+## Bugs
+- Fix default oauth paths [#4725](https://github.com/appwrite/appwrite/pull/4725)
+- Fix session expiration, and expired session deletion [#4739](https://github.com/appwrite/appwrite/pull/4739)
+- Fix processing status on sync executions [#4737](https://github.com/appwrite/appwrite/pull/4737)
+- Fix Locale API returning Unknown continent [#4761](https://github.com/appwrite/appwrite/pull/4761)
+
+# Version 1.1.1
## Bugs
- Fix Deletes worker using incorrect device for file deletion [#4662](https://github.com/appwrite/appwrite/pull/4662)
- Fix Migration for Stats adding the region attribute [#4704](https://github.com/appwrite/appwrite/pull/4704)
diff --git a/Dockerfile b/Dockerfile
index 49df4b35e0..aed8623e53 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,12 @@ COPY app/console /usr/local/src/console
WORKDIR /usr/local/src/console
+ARG VITE_GA_PROJECT
+ARG VITE_CONSOLE_MODE
+
+ENV VITE_GA_PROJECT=$VITE_GA_PROJECT
+ENV VITE_CONSOLE_MODE=$VITE_CONSOLE_MODE
+
RUN npm ci
RUN npm run build
@@ -297,6 +303,7 @@ RUN mkdir -p /storage/uploads && \
# Executables
RUN chmod +x /usr/local/bin/doctor && \
+ chmod +x /usr/local/bin/patch-create-missing-schedules && \
chmod +x /usr/local/bin/maintenance && \
chmod +x /usr/local/bin/volume-sync && \
chmod +x /usr/local/bin/edge-sync && \
diff --git a/README-CN.md b/README-CN.md
index 4f8156f2ce..6f00cebf10 100644
--- a/README-CN.md
+++ b/README-CN.md
@@ -64,7 +64,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
### Windows
@@ -76,7 +76,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
#### PowerShell
@@ -86,7 +86,7 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。
diff --git a/README.md b/README.md
index 6942597115..0e613204c4 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
### Windows
@@ -87,7 +87,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
#### PowerShell
@@ -97,7 +97,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
- appwrite/appwrite:1.1.1
+ appwrite/appwrite:1.1.2
```
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after installation completes.
diff --git a/app/config/collections.php b/app/config/collections.php
index 66f8767c22..63703d62f1 100644
--- a/app/config/collections.php
+++ b/app/config/collections.php
@@ -3408,7 +3408,7 @@ $collections = [
'$id' => ID::custom('mimeType'),
'type' => Database::VAR_STRING,
'format' => '',
- 'size' => 127, // https://tools.ietf.org/html/rfc4288#section-4.2
+ 'size' => 255, // https://tools.ietf.org/html/rfc4288#section-4.2
'signed' => true,
'required' => false,
'default' => null,
diff --git a/app/config/errors.php b/app/config/errors.php
index e4dc3d5b4d..c5c6a489b8 100644
--- a/app/config/errors.php
+++ b/app/config/errors.php
@@ -70,7 +70,7 @@ return [
],
Exception::GENERAL_ROUTE_NOT_FOUND => [
'name' => Exception::GENERAL_ROUTE_NOT_FOUND,
- 'description' => 'The requested route was not found. Please refer to the docs and try again.',
+ 'description' => 'The requested route was not found. Please refer to the API docs and try again.',
'code' => 404,
],
Exception::GENERAL_CURSOR_NOT_FOUND => [
@@ -486,7 +486,7 @@ return [
],
Exception::PROJECT_PROVIDER_UNSUPPORTED => [
'name' => Exception::PROJECT_PROVIDER_UNSUPPORTED,
- 'description' => 'The chosen OAuth provider is unsupported. Please check the docs for the complete list of supported OAuth providers.',
+ 'description' => 'The chosen OAuth provider is unsupported. Please check the Create OAuth2 Session docs for the complete list of supported OAuth providers.',
'code' => 501,
],
Exception::PROJECT_INVALID_SUCCESS_URL => [
diff --git a/app/config/variables.php b/app/config/variables.php
index 1eb2688c62..85c7a04f25 100644
--- a/app/config/variables.php
+++ b/app/config/variables.php
@@ -877,7 +877,16 @@ return [
'required' => false,
'question' => '',
'filter' => ''
- ]
+ ],
+ [
+ 'name' => '_APP_FUNCTIONS_MAINTENANCE_INTERVAL',
+ 'description' => 'Interval how often executor checks for inactive runimes. The default value is 60 seconds.',
+ 'introduction' => '1.2.0',
+ 'default' => '60',
+ 'required' => false,
+ 'question' => '',
+ 'filter' => ''
+ ],
],
],
[
@@ -929,6 +938,15 @@ return [
'question' => '',
'filter' => ''
],
+ [
+ 'name' => '_APP_MAINTENANCE_RETENTION_USAGE_HOURLY',
+ 'description' => 'The maximum duration (in seconds) upto which to retain hourly usage metrics. The default value is 8640000 seconds (100 days).',
+ 'introduction' => '',
+ 'default' => '8640000',
+ 'required' => false,
+ 'question' => '',
+ 'filter' => ''
+ ],
[
'name' => '_APP_MAINTENANCE_RETENTION_SCHEDULES',
'description' => 'Schedules deletion interval ( in seconds ) ',
diff --git a/app/console b/app/console
index 4e2cecefb5..43891a526e 160000
--- a/app/console
+++ b/app/console
@@ -1 +1 @@
-Subproject commit 4e2cecefb571104f0dbbe5a578729f0e17a10242
+Subproject commit 43891a526e061454617cbb13def3c4901d99a7f1
diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php
index d973ffd14c..346820d699 100644
--- a/app/controllers/api/account.php
+++ b/app/controllers/api/account.php
@@ -41,8 +41,8 @@ use Utopia\Validator\Assoc;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
-$oauthDefaultSuccess = '/v1/auth/oauth2/success';
-$oauthDefaultFailure = '/v1/auth/oauth2/failure';
+$oauthDefaultSuccess = '/auth/oauth2/success';
+$oauthDefaultFailure = '/auth/oauth2/failure';
App::post('/v1/account')
->desc('Create Account')
@@ -427,8 +427,6 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
throw new Exception(Exception::PROJECT_INVALID_FAILURE_URL);
}
- $state['failure'] = null;
-
$accessToken = $oauth2->getAccessToken($code);
$refreshToken = $oauth2->getRefreshToken($code);
$accessTokenExpiry = $oauth2->getAccessTokenExpiry($code);
diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php
index 8148303a99..6fe7c67e69 100644
--- a/app/controllers/api/functions.php
+++ b/app/controllers/api/functions.php
@@ -1119,7 +1119,7 @@ App::post('/v1/functions/:functionId/executions')
'functionId' => $function->getId(),
'deploymentId' => $deployment->getId(),
'trigger' => 'http', // http / schedule / event
- 'status' => 'waiting', // waiting / processing / completed / failed
+ 'status' => $async ? 'waiting' : 'processing', // waiting / processing / completed / failed
'statusCode' => 0,
'response' => '',
'stderr' => '',
diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php
index 3aee339dfe..6d824da055 100644
--- a/app/controllers/api/locale.php
+++ b/app/controllers/api/locale.php
@@ -40,7 +40,6 @@ App::get('/v1/locale')
$output['countryCode'] = $record['country']['iso_code'];
$output['country'] = $locale->getText('countries.' . strtolower($record['country']['iso_code']), $locale->getText('locale.country.unknown'));
$output['continent'] = $locale->getText('continents.' . strtolower($record['continent']['code']), $locale->getText('locale.country.unknown'));
- $output['continent'] = (isset($continents[$record['continent']['code']])) ? $continents[$record['continent']['code']] : $locale->getText('locale.country.unknown');
$output['continentCode'] = $record['continent']['code'];
$output['eu'] = (\in_array($record['country']['iso_code'], $eu)) ? true : false;
diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php
index 49b493f00a..58867bb49c 100644
--- a/app/controllers/api/project.php
+++ b/app/controllers/api/project.php
@@ -27,8 +27,8 @@ App::get('/v1/project/usage')
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
$periods = [
'24h' => [
- 'period' => '30m',
- 'limit' => 48,
+ 'period' => '1h',
+ 'limit' => 24,
],
'7d' => [
'period' => '1d',
@@ -82,7 +82,7 @@ App::get('/v1/project/usage')
while ($backfill > 0) {
$last = $limit - $backfill - 1; // array index of last added metric
$diff = match ($period) { // convert period to seconds for unix timestamp math
- '30m' => 1800,
+ '1h' => 3600,
'1d' => 86400,
};
$stats[$metric][] = [
diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php
index ac2bb675b5..5fef7eab78 100644
--- a/app/controllers/api/projects.php
+++ b/app/controllers/api/projects.php
@@ -59,7 +59,7 @@ App::post('/v1/projects')
->param('projectId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `ID.unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
->param('teamId', '', new UID(), 'Team unique ID.')
- ->param('region', '', new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn($config) => !$config['disabled']))), 'Project Region.')
+ ->param('region', App::getEnv('_APP_REGION', 'default'), new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn($config) => !$config['disabled']))), 'Project Region.', true)
->param('description', '', new Text(256), 'Project description. Max length: 256 chars.', true)
->param('logo', '', new Text(1024), 'Project logo.', true)
->param('url', '', new URL(), 'Project URL.', true)
diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php
index db1ff5936c..572b6f02a8 100644
--- a/app/controllers/api/teams.php
+++ b/app/controllers/api/teams.php
@@ -721,7 +721,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->setAttribute('confirm', true)
;
- $user->setAttribute('emailVerification', true);
+ $user = Authorization::skip(fn() => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true)));
// Log user in
diff --git a/app/controllers/general.php b/app/controllers/general.php
index 069a918680..0c10dd46e9 100644
--- a/app/controllers/general.php
+++ b/app/controllers/general.php
@@ -223,7 +223,9 @@ App::init()
return $response->redirect('https://' . $request->getHostname() . $request->getURI());
}
+ }
+ if ($request->getProtocol() === 'https') {
$response->addHeader('Strict-Transport-Security', 'max-age=' . (60 * 60 * 24 * 126)); // 126 days
}
diff --git a/app/init.php b/app/init.php
index 20f53375fb..09a1062d47 100644
--- a/app/init.php
+++ b/app/init.php
@@ -100,7 +100,7 @@ const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate pe
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
const APP_CACHE_BUSTER = 501;
-const APP_VERSION_STABLE = '1.1.1';
+const APP_VERSION_STABLE = '1.1.2';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
@@ -553,10 +553,16 @@ $register->set('pools', function () {
],
];
- $instances = 3; // REST, Realtime, CLI
- $workerCount = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6));
- $maxConnections = App::getenv('_APP_CONNECTIONS_MAX', 251);
- $instanceConnections = $maxConnections / $instances;
+ $maxConnections = App::getEnv('_APP_CONNECTIONS_MAX', 151);
+ $instanceConnections = $maxConnections / App::getEnv('_APP_POOL_CLIENTS', 14);
+
+ $multiprocessing = App::getEnv('_APP_SERVER_MULTIPROCESS', 'disabled') === 'enabled';
+
+ if ($multiprocessing) {
+ $workerCount = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6));
+ } else {
+ $workerCount = 1;
+ }
if ($workerCount > $instanceConnections) {
throw new \Exception('Pool size is too small. Increase the number of allowed database connections or decrease the number of workers.', 500);
@@ -908,9 +914,11 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
Authorization::setDefaultStatus(true);
Auth::setCookieName('a_session_' . $project->getId());
+ $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
if (APP_MODE_ADMIN === $mode) {
Auth::setCookieName('a_session_' . $console->getId());
+ $authDuration = Auth::TOKEN_EXPIRATION_LOGIN_LONG;
}
$session = Auth::decodeSession(
@@ -948,8 +956,6 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
$user = $dbForConsole->getDocument('users', Auth::$unique);
}
- $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
-
if (
$user->isEmpty() // Check a document has been found in the DB
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration)
diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml
index dc7549aa3f..cc53fb8854 100644
--- a/app/views/install/compose.phtml
+++ b/app/views/install/compose.phtml
@@ -139,6 +139,7 @@ services:
- _APP_MAINTENANCE_RETENTION_CACHE
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
+ - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
- _APP_MAINTENANCE_RETENTION_SCHEDULES
- _APP_SMS_PROVIDER
- _APP_SMS_FROM
@@ -483,44 +484,13 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
+ - _APP_USAGE_AGGREGATION_INTERVAL
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_INFLUXDB_HOST
- _APP_INFLUXDB_PORT
- - _APP_USAGE_TIMESERIES_INTERVAL
- - _APP_LOGGING_PROVIDER
- - _APP_LOGGING_CONFIG
-
- appwrite-usage-database:
- image: /:
- entrypoint:
- - usage
- - --type=database
- container_name: appwrite-usage-database
- <<: *x-logging
- restart: unless-stopped
- networks:
- - appwrite
- depends_on:
- - influxdb
- - mariadb
- environment:
- - _APP_ENV
- - _APP_OPENSSL_KEY_V1
- - _APP_DB_HOST
- - _APP_DB_PORT
- - _APP_DB_SCHEMA
- - _APP_DB_USER
- - _APP_DB_PASS
- - _APP_REDIS_HOST
- - _APP_REDIS_PORT
- - _APP_REDIS_USER
- - _APP_REDIS_PASS
- - _APP_INFLUXDB_HOST
- - _APP_INFLUXDB_PORT
- - _APP_USAGE_TIMESERIES_INTERVAL
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
@@ -558,6 +528,7 @@ services:
environment:
- OPR_EXECUTOR_CONNECTION_STORAGE=$_APP_CONNECTIONS_STORAGE
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
+ - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
diff --git a/app/workers/builds.php b/app/workers/builds.php
index 6b2cfcf66b..d26f07ab75 100644
--- a/app/workers/builds.php
+++ b/app/workers/builds.php
@@ -254,6 +254,7 @@ class BuildsV1 extends Worker
$statsd = $register->get('statsd');
$usage = new Stats($statsd);
$usage
+ ->setParam('projectInternalId', $project->getInternalId())
->setParam('projectId', $project->getId())
->setParam('functionId', $function->getId())
->setParam('builds.{scope}.compute', 1)
diff --git a/app/workers/deletes.php b/app/workers/deletes.php
index cd33ed0b79..458b341a45 100644
--- a/app/workers/deletes.php
+++ b/app/workers/deletes.php
@@ -1,5 +1,6 @@
deleteExpiredSessions($this->args['datetime']);
+ $this->deleteExpiredSessions();
break;
case DELETE_TYPE_CERTIFICATES:
@@ -105,7 +107,7 @@ class DeletesV1 extends Worker
break;
case DELETE_TYPE_USAGE:
- $this->deleteUsageStats($this->args['dateTime1d'], $this->args['hourlyUsageRetentionDatetime']);
+ $this->deleteUsageStats($this->args['hourlyUsageRetentionDatetime']);
break;
case DELETE_TYPE_CACHE_BY_RESOURCE:
@@ -132,8 +134,7 @@ class DeletesV1 extends Worker
*/
protected function deleteSchedules(string $datetime): void
{
-
- $this->deleteByGroup(
+ $this->listByGroup(
'schedules',
[
Query::equal('region', [App::getEnv('_APP_REGION', 'default')]),
@@ -143,7 +144,6 @@ class DeletesV1 extends Worker
],
$this->getConsoleDB(),
function (Document $document) {
- Console::info('Querying schedule for function ' . $document->getAttribute('resourceId'));
$project = $this->getConsoleDB()->getDocument('projects', $document->getAttribute('projectId'));
if ($project->isEmpty()) {
@@ -253,13 +253,13 @@ class DeletesV1 extends Worker
}
/**
- * @param string $datetime1d
* @param string $hourlyUsageRetentionDatetime
*/
protected function deleteUsageStats(string $hourlyUsageRetentionDatetime)
{
$this->deleteForProjectIds(function (Document $project) use ($hourlyUsageRetentionDatetime) {
$dbForProject = $this->getProjectDB($project);
+ // Delete Usage stats
$this->deleteByGroup('stats', [
Query::lessThan('time', $hourlyUsageRetentionDatetime),
Query::equal('period', ['1h']),
@@ -354,16 +354,20 @@ class DeletesV1 extends Worker
});
}
- /**
- * @param string $datetime
- */
- protected function deleteExpiredSessions(string $datetime): void
+ protected function deleteExpiredSessions(): void
{
- $this->deleteForProjectIds(function (Document $project) use ($datetime) {
+ $consoleDB = $this->getConsoleDB();
+
+ $this->deleteForProjectIds(function (Document $project) use ($consoleDB) {
$dbForProject = $this->getProjectDB($project);
+
+ $project = $consoleDB->getDocument('projects', $project->getId());
+ $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
+ $expired = DateTime::addSeconds(new \DateTime(), -1 * $duration);
+
// Delete Sessions
$this->deleteByGroup('sessions', [
- Query::lessThan('expire', $datetime)
+ Query::lessThan('$createdAt', $expired)
], $dbForProject);
});
}
@@ -570,6 +574,7 @@ class DeletesV1 extends Worker
*/
protected function deleteForProjectIds(callable $callback): void
{
+ // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document
$count = 0;
$chunk = 0;
$limit = 50;
@@ -633,6 +638,43 @@ class DeletesV1 extends Worker
Console::info("Deleted {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
}
+ /**
+ * @param string $collection collectionID
+ * @param Query[] $queries
+ * @param Database $database
+ * @param callable $callback
+ */
+ protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
+ {
+ $count = 0;
+ $chunk = 0;
+ $limit = 50;
+ $results = [];
+ $sum = $limit;
+
+ $executionStart = \microtime(true);
+
+ while ($sum === $limit) {
+ $chunk++;
+
+ $results = $database->find($collection, \array_merge([Query::limit($limit)], $queries));
+
+ $sum = count($results);
+
+ foreach ($results as $document) {
+ if (is_callable($callback)) {
+ $callback($document);
+ }
+
+ $count++;
+ }
+ }
+
+ $executionEnd = \microtime(true);
+
+ Console::info("Listed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
+ }
+
/**
* @param Document $document certificates document
*/
diff --git a/app/workers/functions.php b/app/workers/functions.php
index 3047bf027e..31e64a2bb4 100644
--- a/app/workers/functions.php
+++ b/app/workers/functions.php
@@ -152,6 +152,10 @@ Server::setResource('execute', function () {
->setAttribute('status', 'failed')
->setAttribute('statusCode', $th->getCode())
->setAttribute('stderr', $th->getMessage());
+
+ Console::error($th->getTraceAsString());
+ Console::error($th->getFile());
+ Console::error($th->getLine());
Console::error($th->getMessage());
}
@@ -205,7 +209,7 @@ Server::setResource('execute', function () {
$usage
->setParam('projectId', $project->getId())
->setParam('projectInternalId', $project->getInternalId())
- ->setParam('functionId', $function->getId())
+ ->setParam('functionId', $function->getId()) // TODO: We should use functionInternalId in usage stats
->setParam('executions.{scope}.compute', 1)
->setParam('executionStatus', $execution->getAttribute('status', ''))
->setParam('executionTime', $execution->getAttribute('duration'))
@@ -272,7 +276,7 @@ $server->job()
queueForFunctions: $queueForFunctions,
trigger: 'event',
event: $events[0],
- eventData: $eventData,
+ eventData: \is_string($eventData) ? $eventData : \json_encode($eventData),
user: $user,
data: null,
executionId: null,
diff --git a/bin/patch-create-missing-schedules b/bin/patch-create-missing-schedules
new file mode 100644
index 0000000000..e38d3e9a6f
--- /dev/null
+++ b/bin/patch-create-missing-schedules
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+php /usr/src/code/app/cli.php patch-create-missing-schedules $@
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 3e3b6b3415..440fd059bb 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -33,15 +33,6 @@ services:
- 8080:80
- 443:443
- 9500:8080
- ulimits:
- nofile:
- soft: 655350
- hard: 655350
- sysctls:
- - net.core.somaxconn=1024
- - net.ipv4.tcp_rmem=1024 4096 16384
- - net.ipv4.tcp_wmem=1024 4096 16384
- - net.ipv4.ip_local_port_range=1025 65535
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- appwrite-config:/storage/config:ro
@@ -62,7 +53,8 @@ services:
DEBUG: false
TESTING: true
VERSION: dev
- ports:
+ VITE_CONSOLE_MODE: self-hosted
+ ports:
- 9501:80
networks:
- appwrite
@@ -93,6 +85,7 @@ services:
- ./public:/usr/src/code/public
- ./src:/usr/src/code/src
- ./dev:/usr/local/dev
+
#- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache
depends_on:
- mariadb
@@ -106,6 +99,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_SERVER_MULTIPROCESS=enabled
- _APP_LOCALE
- _APP_CONSOLE_WHITELIST_ROOT
- _APP_CONSOLE_WHITELIST_EMAILS
@@ -126,6 +120,7 @@ services:
- _APP_DB_USER
- _APP_DB_PASS
- _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -205,6 +200,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_SERVER_MULTIPROCESS=enabled
- _APP_OPTIONS_ABUSE
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
@@ -213,6 +209,7 @@ services:
- _APP_DB_USER
- _APP_DB_PASS
- _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -335,6 +332,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
@@ -366,6 +365,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -402,6 +403,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -435,6 +438,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
@@ -473,6 +478,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
@@ -510,6 +517,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -548,6 +557,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
@@ -579,6 +590,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -604,6 +617,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
- _APP_OPENSSL_KEY_V1
@@ -624,6 +639,7 @@ services:
- _APP_MAINTENANCE_RETENTION_CACHE
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
+ - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
- _APP_MAINTENANCE_RETENTION_SCHEDULES
appwrite-edge-sync:
@@ -676,6 +692,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -684,6 +702,7 @@ services:
- _APP_DB_PASS
- _APP_INFLUXDB_HOST
- _APP_INFLUXDB_PORT
+ - _APP_USAGE_AGGREGATION_INTERVAL
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -691,7 +710,6 @@ services:
- _APP_CONNECTIONS_DB_CONSOLE
- _APP_CONNECTIONS_DB_PROJECT
- _APP_CONNECTIONS_CACHE
- - _APP_USAGE_TIMESERIES_INTERVAL
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
@@ -711,6 +729,8 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
+ - _APP_CONNECTIONS_MAX
+ - _APP_POOL_CLIENTS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -731,7 +751,7 @@ services:
hostname: exc1
<<: *x-logging
stop_signal: SIGINT
- image: openruntimes/executor:0.1.4
+ image: openruntimes/executor:0.1.6
networks:
- appwrite
- runtimes
@@ -743,6 +763,7 @@ services:
environment:
- OPR_EXECUTOR_CONNECTION_STORAGE=$_APP_CONNECTIONS_STORAGE
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
+ - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
@@ -862,7 +883,7 @@ services:
- 9506:8080
networks:
- appwrite
-
+
# appwrite-volume-sync:
# entrypoint: volume-sync
# <<: *x-logging
@@ -872,8 +893,8 @@ services:
# - --source=/data/src/ --destination=/data/dest/ --interval=10
# networks:
# - appwrite
- # # volumes: # Mount the rsync source and destination directories
- # # - /nfs/config:/data/src
+ # # volumes: # Mount the rsync source and destination directories
+ # # - /nfs/config:/data/src
# # - /storage/config:/data/dest
# redis-commander:
diff --git a/docs/examples/1.1.x/client-android/java/account/create-anonymous-session.md b/docs/examples/1.1.x/client-android/java/account/create-anonymous-session.md
index 7d2123b58d..b1a2a25828 100644
--- a/docs/examples/1.1.x/client-android/java/account/create-anonymous-session.md
+++ b/docs/examples/1.1.x/client-android/java/account/create-anonymous-session.md
@@ -1,18 +1,46 @@
-import io.appwrite.Client;
-import io.appwrite.coroutines.CoroutineCallback;
-import io.appwrite.services.Account;
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import io.appwrite.Client
+import io.appwrite.services.Account
-Client client = new Client(context)
- .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
- .setProject("5df5acd0d48c2"); // Your project ID
+public class MainActivity extends AppCompatActivity {
-Account account = new Account(client);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
-account.createAnonymousSession(new CoroutineCallback<>((result, error) -> {
- if (error != null)
- error.printStackTrace();
- return;
+ Client client = new Client(getApplicationContext())
+ .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2"); // Your project ID
+
+ Account account = new Account(client);
+
+ account.createAnonymousSession(new Continuation