From 9af06b4b59b8cb3d6c0c0ea0cebe757638e6a90d Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 17 Feb 2017 18:19:53 -0500 Subject: [PATCH] Add in query caching on server view --- .env.example | 2 +- CHANGELOG.md | 5 ++ app/Console/Commands/UpdateEnvironment.php | 4 ++ app/Events/Server/Saved.php | 45 +++++++++++++++++ app/Events/Server/Saving.php | 45 +++++++++++++++++ app/Events/Server/Updated.php | 45 +++++++++++++++++ app/Events/Server/Updating.php | 45 +++++++++++++++++ app/Http/Controllers/Base/IndexController.php | 2 +- app/Models/Server.php | 20 +++++--- app/Models/User.php | 4 +- app/Observers/ServerObserver.php | 49 +++++++++++++++++++ config/cache.php | 6 ++- config/debugbar.php | 8 +-- .../pterodactyl/layouts/master.blade.php | 2 +- 14 files changed, 263 insertions(+), 19 deletions(-) create mode 100644 app/Events/Server/Saved.php create mode 100644 app/Events/Server/Saving.php create mode 100644 app/Events/Server/Updated.php create mode 100644 app/Events/Server/Updating.php diff --git a/.env.example b/.env.example index fa7e20965..ed3a56b68 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret -CACHE_DRIVER=file +CACHE_DRIVER=memcached SESSION_DRIVER=database MAIL_DRIVER=smtp diff --git a/CHANGELOG.md b/CHANGELOG.md index e5f206283..12a23d724 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ## v0.6.0-pre.3 (Courageous Carniadactylus) ### Fixed * `[pre.2]` — Fixes bug where servers could not be manually deployed to nodes due to a broken SQL call. +* `[pre.2]` — Fixes inability to edit a server due to owner_id issues. + +### Changed +* `[pre.2]` — File Manager now displays relevant information on all screen sizes, and includes better button clicking mechanics for dropdown menu. +* Reduced the number of database queries being executed when viewing a specific server. This is done by caching the query for up to 60 minutes in memcached. ## v0.6.0-pre.2 (Courageous Carniadactylus) ### Fixed diff --git a/app/Console/Commands/UpdateEnvironment.php b/app/Console/Commands/UpdateEnvironment.php index 3805ffd51..aa3dcfe7f 100644 --- a/app/Console/Commands/UpdateEnvironment.php +++ b/app/Console/Commands/UpdateEnvironment.php @@ -134,6 +134,10 @@ class UpdateEnvironment extends Command $variables['APP_TIMEZONE'] = $this->option('timezone'); } + $variables['APP_THEME'] = 'pterodactyl'; + $variables['CACHE_DRIVER'] = 'memcached'; + $variables['SESSION_DRIVER'] = 'database'; + $bar = $this->output->createProgressBar(count($variables)); $this->line('Writing new environment configuration to file.'); diff --git a/app/Events/Server/Saved.php b/app/Events/Server/Saved.php new file mode 100644 index 000000000..08700e3cb --- /dev/null +++ b/app/Events/Server/Saved.php @@ -0,0 +1,45 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Events\Server; + +use Pterodactyl\Models\Server; +use Illuminate\Queue\SerializesModels; + +class Saved +{ + use SerializesModels; + + public $server; + + /** + * Create a new event instance. + * + * @return void + */ + public function __construct(Server $server) + { + $this->server = $server; + } +} diff --git a/app/Events/Server/Saving.php b/app/Events/Server/Saving.php new file mode 100644 index 000000000..2c6d3cb4e --- /dev/null +++ b/app/Events/Server/Saving.php @@ -0,0 +1,45 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Events\Server; + +use Pterodactyl\Models\Server; +use Illuminate\Queue\SerializesModels; + +class Saving +{ + use SerializesModels; + + public $server; + + /** + * Create a new event instance. + * + * @return void + */ + public function __construct(Server $server) + { + $this->server = $server; + } +} diff --git a/app/Events/Server/Updated.php b/app/Events/Server/Updated.php new file mode 100644 index 000000000..0310e20c6 --- /dev/null +++ b/app/Events/Server/Updated.php @@ -0,0 +1,45 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Events\Server; + +use Pterodactyl\Models\Server; +use Illuminate\Queue\SerializesModels; + +class Updated +{ + use SerializesModels; + + public $server; + + /** + * Create a new event instance. + * + * @return void + */ + public function __construct(Server $server) + { + $this->server = $server; + } +} diff --git a/app/Events/Server/Updating.php b/app/Events/Server/Updating.php new file mode 100644 index 000000000..f333ede6b --- /dev/null +++ b/app/Events/Server/Updating.php @@ -0,0 +1,45 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Events\Server; + +use Pterodactyl\Models\Server; +use Illuminate\Queue\SerializesModels; + +class Updating +{ + use SerializesModels; + + public $server; + + /** + * Create a new event instance. + * + * @return void + */ + public function __construct(Server $server) + { + $this->server = $server; + } +} diff --git a/app/Http/Controllers/Base/IndexController.php b/app/Http/Controllers/Base/IndexController.php index 6b0bd273e..f6abf4ea4 100644 --- a/app/Http/Controllers/Base/IndexController.php +++ b/app/Http/Controllers/Base/IndexController.php @@ -47,7 +47,7 @@ class IndexController extends Controller public function getIndex(Request $request) { return view('base.index', [ - 'servers' => $request->user()->serverAccessCollection(10)->load('node', 'allocation'), + 'servers' => $request->user()->serverAccessCollection(10), ]); } diff --git a/app/Models/Server.php b/app/Models/Server.php index 5dd5bb357..5e8179254 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -25,6 +25,7 @@ namespace Pterodactyl\Models; use Auth; +use Cache; use Javascript; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; @@ -113,16 +114,19 @@ class Server extends Model */ public static function byUuid($uuid) { - $query = self::with('service', 'node')->where(function ($q) use ($uuid) { - $q->where('uuidShort', $uuid)->orWhere('uuid', $uuid); + // Results are cached because we call this functions a few times on page load. + $result = Cache::remember('Server.byUuid.' . $uuid, 60, function () use ($uuid) { + $query = self::with('service', 'node')->where(function ($q) use ($uuid) { + $q->where('uuidShort', $uuid)->orWhere('uuid', $uuid); + }); + + if (! Auth::user()->isRootAdmin()) { + $query->whereIn('id', Auth::user()->serverAccessArray()); + } + + return $query->first(); }); - if (! Auth::user()->isRootAdmin()) { - $query->whereIn('id', Auth::user()->serverAccessArray()); - } - - $result = $query->first(); - if (! is_null($result)) { $result->daemonSecret = Auth::user()->daemonToken($result); } diff --git a/app/Models/User.php b/app/Models/User.php index abcddf227..131192264 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -186,9 +186,9 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac * * @return Collection */ - public function serverAccessCollection($paginate = null) + public function serverAccessCollection($paginate = null, $load = ['service', 'node', 'allocation']) { - $query = Server::with('service', 'node'); + $query = Server::with($load); if (! $this->isRootAdmin()) { $query->whereIn('id', $this->serverAccessArray()); } diff --git a/app/Observers/ServerObserver.php b/app/Observers/ServerObserver.php index 06778c674..556d1c165 100644 --- a/app/Observers/ServerObserver.php +++ b/app/Observers/ServerObserver.php @@ -24,6 +24,7 @@ namespace Pterodactyl\Observers; +use Cache; use Carbon; use Pterodactyl\Events; use Pterodactyl\Models\Server; @@ -97,4 +98,52 @@ class ServerObserver ->onQueue(env('QUEUE_STANDARD', 'standard')) ); } + + /** + * Listen to the Server saving event. + * + * @param Server $server [description] + * @return [type] [description] + */ + public function saving(Server $server) + { + event(new Events\Server\Saving($server)); + } + + /** + * Listen to the Server saved event. + * + * @param Server $server [description] + * @return [type] [description] + */ + public function saved(Server $server) + { + event(new Events\Server\Saved($server)); + } + + /** + * Listen to the Server saving event. + * + * @param Server $server [description] + * @return [type] [description] + */ + public function updating(Server $server) + { + event(new Events\Server\Updating($server)); + } + + /** + * Listen to the Server saved event. + * + * @param Server $server [description] + * @return [type] [description] + */ + public function updated(Server $server) + { + // Clear Caches + Cache::forget('Server.byUuid.' . $server->uuid); + Cache::forget('Server.byUuid.' . $server->uuidShort); + + event(new Events\Server\Updated($server)); + } } diff --git a/config/cache.php b/config/cache.php index 379135b0e..cb4bbd25d 100644 --- a/config/cache.php +++ b/config/cache.php @@ -13,7 +13,7 @@ return [ | */ - 'default' => env('CACHE_DRIVER', 'file'), + 'default' => env('CACHE_DRIVER', 'memcached'), /* |-------------------------------------------------------------------------- @@ -51,7 +51,9 @@ return [ 'driver' => 'memcached', 'servers' => [ [ - 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100, + 'host' => env('MEMCACHE_DRIVER_HOST', '127.0.0.1'), + 'port' => env('MEMCACHE_DRIVER_PORT', 11211), + 'weight' => 100, ], ], ], diff --git a/config/debugbar.php b/config/debugbar.php index 4c1349b40..4d9d8c45e 100644 --- a/config/debugbar.php +++ b/config/debugbar.php @@ -92,7 +92,7 @@ return [ 'views' => true, // Views with their data 'route' => true, // Current route information 'laravel' => false, // Laravel version and environment - 'events' => false, // All events fired + 'events' => true, // All events fired 'default_request' => false, // Regular or special Symfony request logger 'symfony_request' => true, // Only one can be enabled.. 'mail' => true, // Catch mail messages @@ -119,11 +119,11 @@ return [ ], 'db' => [ 'with_params' => true, // Render SQL with the parameters substituted - 'timeline' => false, // Add the queries to the timeline - 'backtrace' => false, // EXPERIMENTAL: Use a backtrace to find the origin of the query in your files. + 'timeline' => true, // Add the queries to the timeline + 'backtrace' => true, // EXPERIMENTAL: Use a backtrace to find the origin of the query in your files. 'explain' => [ // EXPERIMENTAL: Show EXPLAIN output on queries 'enabled' => false, - 'types' => ['SELECT'], // array('SELECT', 'INSERT', 'UPDATE', 'DELETE'); for MySQL 5.6.3+ + 'types' => ['SELECT', 'INSERT', 'UPDATE', 'DELETE'], // array('SELECT', 'INSERT', 'UPDATE', 'DELETE'); for MySQL 5.6.3+ ], 'hints' => true, // Show hints for common mistakes ], diff --git a/resources/themes/pterodactyl/layouts/master.blade.php b/resources/themes/pterodactyl/layouts/master.blade.php index 6c6307367..9df07de6e 100644 --- a/resources/themes/pterodactyl/layouts/master.blade.php +++ b/resources/themes/pterodactyl/layouts/master.blade.php @@ -219,7 +219,7 @@
    - @foreach (Auth::user()->serverAccessCollection() as $s) + @foreach (Auth::user()->serverAccessCollection(null, []) as $s)