misc: use hobo.multitenant.spooler (#76747) #55
|
@ -31,7 +31,6 @@ Depends: python3-django-mellon,
|
|||
python3-hobo,
|
||||
python3-lingo (= ${binary:Version}),
|
||||
python3-psycopg2,
|
||||
python3-uwsgidecorators,
|
||||
uwsgi,
|
||||
uwsgi-plugin-python3,
|
||||
${misc:Depends},
|
||||
|
|
|
@ -14,7 +14,7 @@ vacuum = true
|
|||
|
||||
spooler-processes = 3
|
||||
spooler-python-import = lingo.invoicing.spooler
|
||||
spooler-python-import = hobo.provisionning.spooler
|
||||
spooler-python-import = hobo.multitenant.spooler
|
||||
spooler-max-tasks = 20
|
||||
|
||||
master = true
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import copy
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import connection, models, transaction
|
||||
from django.db import models, transaction
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.text import slugify
|
||||
from django.utils.timezone import now
|
||||
|
@ -29,6 +28,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
from lingo.agendas.chrono import ChronoError, lock_events_check
|
||||
from lingo.agendas.models import Agenda
|
||||
from lingo.utils import spooler
|
||||
from lingo.utils.misc import generate_slug
|
||||
|
||||
|
||||
|
@ -171,18 +171,10 @@ class Campaign(models.Model):
|
|||
except Exception:
|
||||
return
|
||||
|
||||
if spool and 'uwsgi' in sys.modules:
|
||||
from lingo.invoicing.spooler import generate_invoices
|
||||
|
||||
tenant = getattr(connection, 'tenant', None)
|
||||
transaction.on_commit(
|
||||
lambda: generate_invoices.spool(
|
||||
campaign_id=str(self.pk), pool_id=str(pool.pk), domain=getattr(tenant, 'domain_url', None)
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
pool.generate_invoices()
|
||||
if spool:
|
||||
spooler.run(pool.generate_invoices)
|
||||
else:
|
||||
pool.generate_invoices()
|
||||
|
||||
|
||||
class Pool(models.Model):
|
||||
|
@ -275,20 +267,30 @@ class Pool(models.Model):
|
|||
final_pool.completed_at = None
|
||||
final_pool.save()
|
||||
|
||||
if 'uwsgi' in sys.modules:
|
||||
from lingo.invoicing.spooler import populate_from_draft
|
||||
spooler.run(final_pool.populate_from_draft_spooler, self)
|
||||
|
||||
tenant = getattr(connection, 'tenant', None)
|
||||
transaction.on_commit(
|
||||
lambda: populate_from_draft.spool(
|
||||
draft_pool_id=str(self.pk),
|
||||
final_pool_id=str(final_pool.pk),
|
||||
domain=getattr(tenant, 'domain_url', None),
|
||||
)
|
||||
)
|
||||
def populate_from_draft_spooler(self, draft_pool):
|
||||
# we may be in the spooler, refresh our view of the instances, they
|
||||
# could no exist anymore
|
||||
try:
|
||||
draft_pool.refresh_from_db()
|
||||
self.refresh_from_db()
|
||||
except Pool.DoesNotExist:
|
||||
return
|
||||
|
||||
final_pool.populate_from_draft(self)
|
||||
# FIXME: needs comment for why we do all those checks, they were
|
||||
# already needed before in the spooler function
|
||||
if draft_pool.status != 'completed' or not draft_pool.draft:
|
||||
return
|
||||
|
||||
if draft_pool.campaign.pool_set.filter(created_at__gt=draft_pool.created_at, draft=True).exists():
|
||||
return
|
||||
|
||||
# check final_pool = self
|
||||
if self.status != 'registered' or self.draft:
|
||||
return
|
||||
|
||||
self.populate_from_draft(draft_pool)
|
||||
|
||||
def populate_from_draft(self, draft_pool):
|
||||
try:
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
# lingo - payment and billing system
|
||||
# Copyright (C) 2023 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.db import connection
|
||||
from uwsgidecorators import spool # pylint: disable=import-error
|
||||
|
||||
from lingo.invoicing.models import Pool
|
||||
|
||||
|
||||
def set_connection(domain):
|
||||
from hobo.multitenant.middleware import TenantMiddleware # pylint: disable=import-error
|
||||
|
||||
tenant = TenantMiddleware.get_tenant_by_hostname(domain)
|
||||
connection.set_tenant(tenant)
|
||||
|
||||
|
||||
@spool
|
||||
def generate_invoices(args):
|
||||
if args.get('domain'):
|
||||
# multitenant installation
|
||||
set_connection(args['domain'])
|
||||
|
||||
try:
|
||||
pool = Pool.objects.get(
|
||||
campaign__pk=args['campaign_id'], pk=args['pool_id'], status='registered', draft=True
|
||||
)
|
||||
except Pool.DoesNotExist:
|
||||
return
|
||||
|
||||
pool.generate_invoices()
|
||||
|
||||
|
||||
@spool
|
||||
def populate_from_draft(args):
|
||||
if args.get('domain'):
|
||||
# multitenant installation
|
||||
set_connection(args['domain'])
|
||||
|
||||
try:
|
||||
draft_pool = Pool.objects.get(pk=args['draft_pool_id'], status='completed', draft=True)
|
||||
except Pool.DoesNotExist:
|
||||
return
|
||||
|
||||
if draft_pool.campaign.pool_set.filter(created_at__gt=draft_pool.created_at, draft=True).exists():
|
||||
return
|
||||
|
||||
try:
|
||||
final_pool = Pool.objects.get(pk=args['final_pool_id'], status='registered', draft=False)
|
||||
except Pool.DoesNotExist:
|
||||
return
|
||||
|
||||
final_pool.populate_from_draft(draft_pool)
|
|
@ -202,6 +202,8 @@ DEBUG_TOOLBAR_CONFIG = {'SHOW_TOOLBAR_CALLBACK': debug_show_toolbar}
|
|||
|
||||
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'lingo.api.utils.exception_handler'}
|
||||
|
||||
USE_NEW_SPOOLER = True
|
||||
|
||||
local_settings_file = os.environ.get(
|
||||
'LINGO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py')
|
||||
)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# lingo - payment and billing system
|
||||
# Copyright (C) 2023 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
try:
|
||||
from hobo.multitenant.spooler import run # pylint: disable=unused-import
|
||||
except ImportError:
|
||||
import pickle
|
||||
|
||||
def run(func, *args, **kwargs):
|
||||
try:
|
||||
pickle.dumps((func, args, kwargs))
|
||||
except Exception:
|
||||
raise ValueError(f'{(func, args, kwargs)} are unpicklable')
|
||||
func(*args, **kwargs)
|
Loading…
Reference in New Issue