use singletons to reduce need to recreate the same objects

This commit is contained in:
Aaron Moses 2019-11-17 11:59:43 +00:00
parent e493abf784
commit fca0bd73ad
16 changed files with 255 additions and 28 deletions

37
Docker-compose.yaml Normal file
View File

@ -0,0 +1,37 @@
# Usage:
# docker-compose build && docker-compose up
version: '2'
services:
grocy-nginx:
image: grocy/grocy-docker:nginx
# build:
# context: .
# dockerfile: Dockerfile-grocy-nginx
depends_on:
- grocy
ports:
- '80:80'
- '443:443'
volumes_from:
- grocy
container_name: grocy-nginx
grocy:
image: grocy/grocy-docker:grocy
build:
context: .
dockerfile: Dockerfile
expose:
- 9000
volumes:
- ./data_store:/www/data
environment:
PHP_MEMORY_LIMIT: 512M
MAX_UPLOAD: 50M
PHP_MAX_FILE_UPLOAD: 200
PHP_MAX_POST: 100M
GROCY_CULTURE: en
container_name: grocy
#volumes:
# database:

78
Dockerfile Normal file
View File

@ -0,0 +1,78 @@
FROM php:7.2-fpm-alpine
LABEL maintainer="Talmai Oliveira <to@talm.ai>"
RUN docker-php-ext-install opcache
#COPY grocy.tar.gz .
RUN echo $PWD
RUN mkdir /var/www/html/grocy-dev
ADD ./ /var/www/html/grocy-dev/
RUN apk update && \
apk upgrade && \
apk add --no-cache --update yarn git python py-pip wget freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev && \
docker-php-ext-configure gd \
--with-gd \
--with-freetype-dir=/usr/include/ \
--with-png-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ && \
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
docker-php-ext-install -j${NPROC} gd && \
mkdir -p /www && \
# Set environments
sed -i "s|;*daemonize\s*=\s*yes|daemonize = no|g" /usr/local/etc/php-fpm.conf && \
sed -i "s|;*listen\s*=\s*127.0.0.1:9000|listen = 9000|g" /usr/local/etc/php-fpm.conf && \
sed -i "s|;*listen\s*=\s*/||g" /usr/local/etc/php-fpm.conf && \
sed -i "s|;*chdir\s*=\s*/var/www|chdir = /www|g" /usr/local/etc/php-fpm.d/www.conf && \
#echo "[opcache]" >> /usr/local/etc/php-fpm.d/www.conf && \
#echo "zend_extension=opcache.so" >> /usr/local/etc/php-fpm.conf && \
#echo "opcache.enable=1" >> /usr/local/etc/php-fpm.d/www.conf && \
#echo "opcache.memory_consumption=128" >> /usr/local/etc/php-fpm.d/www.conf && \
#echo "opcache.interned_strings_buffer=8" >> /usr/local/etc/php-fpm.d/www.conf && \
wget https://getcomposer.org/installer -O - -q | php -- --quiet && \
#pip install lastversion==0.2.4 && \
#mkdir -p /tmp/download && \
#wget -t 3 -T 30 -nv -O "grocy.tar.gz" $(lastversion --source grocy/grocy) && \
#tar xzf grocy.tar.gz && \
#rm -f grocy.tar.gz && \
cd grocy-dev && \
echo $PWD && \
ls -lrt . && \
mv public /www/public && \
mv controllers /www/controllers && \
mv data /www/data && \
mv helpers /www/helpers && \
mv localization/ /www/localization && \
mv middleware/ /www/middleware && \
mv migrations/ /www/migrations && \
mv publication_assets/ /www/publication_assets && \
mv services/ /www/services && \
mv views/ /www/views && \
mv .yarnrc /www/ && \
mv *.php /www/ && \
mv *.json /www/ && \
mv composer.* /root/.composer/ && \
mv *yarn* /www/ && \
mv *.sh /www/ && \
# Cleaning up
rm -rf /tmp/download && \
rm -rf /var/cache/apk/*
# run php composer.phar with -vvv for extra debug information
RUN cd /var/www/html && \
php composer.phar --working-dir=/www/ -n install && \
cp /www/config-dist.php /www/data/config.php && \
cd /www && \
yarn install && \
if [ -d /www/data/viewcache ]; then rm -rf /www/data/viewcache; fi && \
mkdir /www/data/viewcache && \
chown www-data:www-data -R /www/
# Set Workdir
WORKDIR /www/public
# Expose volumes
#VOLUME ["/www"]
# Expose ports
EXPOSE 9000

View File

@ -74,6 +74,14 @@ $appContainer = new \Slim\Container([
]);
$app = new \Slim\App($appContainer);
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "!!!Starting up loading app\n");
fwrite($fp, "!!!".print_r(ini_get_all(),True)."\n");
#fwrite($fp, "!!!".print_r(opcache_get_status(),True)."\n");
fclose($fp);
phpinfo();
// Load routes from separate file
require_once __DIR__ . '/routes.php';

View File

@ -10,13 +10,13 @@ use \Grocy\Services\UsersService;
class BaseController
{
public function __construct(\Slim\Container $container) {
$databaseService = new DatabaseService();
$databaseService = DatabaseService::getInstance();
$this->Database = $databaseService->GetDbConnection();
$localizationService = new LocalizationService(GROCY_CULTURE);
$this->LocalizationService = $localizationService;
$applicationService = new ApplicationService();
$applicationService = ApplicationService::getInstance();
$versionInfo = $applicationService->GetInstalledVersion();
$container->view->set('version', $versionInfo->Version);
$container->view->set('releaseDate', $versionInfo->ReleaseDate);

View File

@ -22,7 +22,7 @@ class OpenApiController extends BaseApiController
public function DocumentationSpec(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$applicationService = new ApplicationService();
$applicationService = ApplicationService::getInstance();
$versionInfo = $applicationService->GetInstalledVersion();
$this->OpenApiSpec->info->version = $versionInfo->Version;

View File

@ -117,6 +117,12 @@ class StockApiController extends BaseApiController
{
$requestBody = $request->getParsedBody();
$result = null;
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "???executing api consume product");
$time_start = microtime(true);
try
{
if ($requestBody === null)
@ -154,12 +160,15 @@ class StockApiController extends BaseApiController
}
$bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId, $recipeId);
return $this->ApiResponse($this->Database->stock_log($bookingId));
$result = $this->ApiResponse($this->Database->stock_log($bookingId));
}
catch (\Exception $ex)
{
return $this->GenericErrorResponse($response, $ex->getMessage());
$result = $this->GenericErrorResponse($response, $ex->getMessage());
}
fwrite($fp, "???API Consume product - Total execution time in seconds: " . round((microtime(true) - $time_start),6) . "\n");
fclose($fp);
return $result;
}
public function ConsumeProductByBarcode(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)

View File

@ -11,6 +11,9 @@ class StockController extends BaseController
public function __construct(\Slim\Container $container)
{
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "!!!constructing StockController\n");
fclose($fp);
parent::__construct($container);
$this->StockService = new StockService();
$this->UserfieldsService = new UserfieldsService();
@ -48,10 +51,15 @@ class StockController extends BaseController
public function Consume(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
return $this->AppContainer->view->render($response, 'consume', [
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "???executing consume stock");
$time_start = microtime(true);
$result = $this->AppContainer->view->render($response, 'consume', [
'products' => $this->Database->products()->orderBy('name'),
'recipes' => $this->Database->recipes()->orderBy('name')
]);
fwrite($fp, "???Total execution time in seconds: " . round((microtime(true) - $time_start),6) . "\n");
fclose($fp);
}
public function Inventory(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)

View File

@ -10,8 +10,8 @@ class SystemApiController extends BaseApiController
public function __construct(\Slim\Container $container)
{
parent::__construct($container);
$this->DatabaseService = new DatabaseService();
$this->ApplicationService = new ApplicationService();
$this->DatabaseService = DatabaseService::getInstance();
$this->ApplicationService = ApplicationService::getInstance();
}
protected $DatabaseService;
@ -39,7 +39,7 @@ class SystemApiController extends BaseApiController
{
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}
}
public function GetSystemInfo(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)

View File

@ -13,7 +13,7 @@ class SystemController extends BaseController
public function __construct(\Slim\Container $container)
{
parent::__construct($container);
$this->ApplicationService = new ApplicationService();
$this->ApplicationService = ApplicationService::getInstance();
}
public function Root(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
@ -85,7 +85,7 @@ class SystemController extends BaseController
if ($entryPage === 'calendar' && constant('GROCY_FEATURE_FLAG_CALENDAR')) {
return '/calendar';
}
// Meal Plan
if ($entryPage === 'mealplan' && constant('GROCY_FEATURE_FLAG_RECIPES')) {
return '/mealplan';

View File

@ -9,7 +9,7 @@ class BaseMiddleware
public function __construct(\Slim\Container $container)
{
$this->AppContainer = $container;
$this->ApplicationService = new ApplicationService();
$this->ApplicationService = ApplicationService::getInstance();
}
protected $AppContainer;

View File

@ -5,17 +5,33 @@ namespace Grocy\Services;
class ApplicationService extends BaseService
{
private $InstalledVersion;
private static $instance = null;
public static function getInstance()
{
if (self::$instance == null)
{
self::$instance = new $self();
}
return self::$instance;
}
private function __construct()
{
parent::__construct();
}
public function GetInstalledVersion()
{
if ($this->InstalledVersion == null)
{
$this->InstalledVersion = json_decode(file_get_contents(__DIR__ . '/../version.json'));
if (GROCY_MODE === 'prerelease')
{
$commitHash = trim(exec('git log --pretty="%h" -n1 HEAD'));
$commitDate = trim(exec('git log --date=iso --pretty="%cd" -n1 HEAD'));
$this->InstalledVersion->Version = "pre-release-$commitHash";
$this->InstalledVersion->ReleaseDate = substr($commitDate, 0, 19);
}

View File

@ -8,7 +8,7 @@ use \Grocy\Services\LocalizationService;
class BaseService
{
public function __construct() {
$this->DatabaseService = new DatabaseService();
$this->DatabaseService = DatabaseService::getInstance();
$this->Database = $this->DatabaseService->GetDbConnection();
$localizationService = new LocalizationService(GROCY_CULTURE);

View File

@ -4,8 +4,59 @@ namespace Grocy\Services;
use \Grocy\Services\ApplicationService;
class PDOWrap
{
private $instance = null;
public function __construct(){
$pars = func_get_args();
$this->instance = is_object($obj='PDO')?$obj:new $obj(
$pars[0],
null,
null,
array(\PDO::ATTR_PERSISTENT => true)
);
return $this;
}
public function __call($name,$pars){
$result = null;
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "PDO::".$name." called with arguments:- ".implode( ", ", $pars)."\n");
$time_start = microtime(true);
if(in_array($name, array("exec","query")))
{
fwrite($fp, array_values($pars)[0] . "\n");
$result = call_user_func_array([$this->instance,$name],$pars);
}else{
$result = call_user_func_array([$this->instance,$name],$pars);
}
fwrite($fp, "Total execution time in seconds: " . round((microtime(true) - $time_start),6) . "\n");
fclose($fp);
return $result;
}
}
class DatabaseService
{
private static $instance = null;
public static function getInstance()
{
if (self::$instance == null)
{
self::$instance = new self();
}
return self::$instance;
}
private static function __construct()
{
parent::__construct();
}
private function GetDbFilePath()
{
if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
@ -16,34 +67,54 @@ class DatabaseService
return GROCY_DATAPATH . '/grocy.db';
}
private $DbConnectionRaw;
#private $DbConnectionRaw;
private static $DbConnectionRaw = null;
/**
* @return \PDO
*/
public function GetDbConnectionRaw()
{
if ($this->DbConnectionRaw == null)
if (self::$DbConnectionRaw == null)
#if ($this->DbConnectionRaw == null)
{
$pdo = new \PDO('sqlite:' . $this->GetDbFilePath());
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "+++Creating new PDO object\n");
$time_start = microtime(true);
$pdo = new PDOWrap('sqlite:' . $this->GetDbFilePath());
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->DbConnectionRaw = $pdo;
self::$DbConnectionRaw = $pdo;
#$this->DbConnectionRaw = $pdo;
fwrite($fp, "+++Total execution time in seconds: " . round((microtime(true) - $time_start),6) . "\n");
fwrite($fp, "+++object created\n");
fclose($fp);
}
return $this->DbConnectionRaw;
return self::$DbConnectionRaw;
#return $this->DbConnectionRaw;
}
private $DbConnection;
#private $DbConnection;
private static $DbConnection = null;
/**
* @return \LessQL\Database
*/
public function GetDbConnection()
{
if ($this->DbConnection == null)
if (self::$DbConnection == null)
#if ($this->DbConnection == null)
{
$this->DbConnection = new \LessQL\Database($this->GetDbConnectionRaw());
$fp = fopen('/www/data/sql.log', 'a');
fwrite($fp, "---creating new LessQL::Database object\n");
$time_start = microtime(true);
self::$DbConnection = new \LessQL\Database($this->GetDbConnectionRaw());
#$this->DbConnection = new \LessQL\Database($this->GetDbConnectionRaw());
fwrite($fp, "---Total execution time in seconds: " . round((microtime(true) - $time_start),6) . "\n");
fwrite($fp, "---object created\n");
fclose($fp);
}
return $this->DbConnection;
return self::$DbConnection;
#return $this->DbConnection;
}
/**

View File

@ -12,7 +12,7 @@ class LocalizationService
public function __construct(string $culture)
{
$this->Culture = $culture;
$this->DatabaseService = new DatabaseService();
$this->DatabaseService = DatabaseService::getInstance();
$this->Database = $this->DatabaseService->GetDbConnection();
$this->LoadLocalizations($culture);

View File

@ -22,7 +22,7 @@ class StockService extends BaseService
$sql = 'SELECT * FROM stock_current WHERE best_before_date IS NOT NULL UNION SELECT id, 0, 0, null, 0, 0, 0 FROM ' . $missingProductsView . ' WHERE id NOT IN (SELECT product_id FROM stock_current)';
}
return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
}

View File

@ -52,7 +52,7 @@
@endif
<button id="save-consume-button" class="btn btn-success">{{ $__t('OK') }}</button>
@if(GROCY_FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING)
<button id="save-mark-as-open-button" class="btn btn-secondary">{{ $__t('Mark as opened') }}</button>
@endif