fix: use separate thread to sync changes to farmOS

i.e. when creating or editing an asset/log, or submitting quick eggs form
This commit is contained in:
Lance Edgar 2026-03-21 20:18:32 -05:00
parent 969497826d
commit 9707c36553
2 changed files with 59 additions and 7 deletions

View file

@ -24,6 +24,7 @@ Base class for WuttaFarm master views
"""
import threading
import time
import requests
from webhelpers2.html import tags
@ -110,17 +111,36 @@ class WuttaFarmMasterView(MasterView):
f.set_readonly("drupal_id")
def persist(self, obj, session=None):
session = session or self.Session()
# save per usual
super().persist(obj, session)
# maybe also sync change to farmOS
if self.app.is_farmos_mirror():
if self.creating:
session.flush() # need the new uuid
client = get_farmos_client_for_user(self.request)
self.auto_sync_to_farmos(client, obj)
thread = threading.Thread(
target=self.auto_sync_to_farmos, args=(client, obj.uuid)
)
thread.start()
def auto_sync_to_farmos(self, client, obj):
self.app.auto_sync_to_farmos(obj, client=client, require=False)
def auto_sync_to_farmos(self, client, uuid):
model = self.app.model
model_class = self.get_model_class()
with self.app.short_session(commit=True) as session:
if user := session.query(model.User).filter_by(username="farmos").first():
session.info["continuum_user_id"] = user.uuid
obj = None
while not obj:
obj = session.get(model_class, uuid)
if not obj:
time.sleep(0.1)
self.app.auto_sync_to_farmos(obj, client=client, require=False)
def get_farmos_entity_type(self):
if self.farmos_entity_type:

View file

@ -24,6 +24,8 @@ Quick Form for "Eggs"
"""
import json
import threading
import time
import colander
from deform.widget import SelectWidget
@ -331,13 +333,43 @@ class EggsQuickForm(QuickFormView):
session.flush()
if self.app.is_farmos_mirror():
if new_unit:
self.app.auto_sync_to_farmos(unit, client=self.farmos_client)
self.app.auto_sync_to_farmos(quantity, client=self.farmos_client)
self.app.auto_sync_to_farmos(log, client=self.farmos_client)
thread = threading.Thread(
target=self.auto_sync_to_farmos,
args=(log.uuid, quantity.uuid, new_unit.uuid if new_unit else None),
)
thread.start()
return log
def auto_sync_to_farmos(self, log_uuid, quantity_uuid, new_unit_uuid):
model = self.app.model
with self.app.short_session(commit=True) as session:
if user := session.query(model.User).filter_by(username="farmos").first():
session.info["continuum_user_id"] = user.uuid
if new_unit_uuid:
new_unit = None
while not new_unit:
new_unit = session.get(model.Unit, new_unit_uuid)
if not new_unit:
time.sleep(0.1)
self.app.auto_sync_to_farmos(unit, client=self.farmos_client)
quantity = None
while not quantity:
quantity = session.get(model.StandardQuantity, quantity_uuid)
if not quantity:
time.sleep(0.1)
self.app.auto_sync_to_farmos(quantity, client=self.farmos_client)
log = None
while not log:
log = session.get(model.HarvestLog, log_uuid)
if not log:
time.sleep(0.1)
self.app.auto_sync_to_farmos(log, client=self.farmos_client)
def redirect_after_save(self, log):
model = self.app.model