20110727

Upgrade in Eupen

Ich mache ein Upgrade in Eupen wegen des Bugs “Lino verweigerte das Löschen nicht immer”. So ein Upgrade ist ja inzwischen Routinearbeit: Zunächst ein dump beim Kunden machen und auf Jana testen, ob es mit der neuen Version eingelesen wird… Upps, und prompt passiert was Neues:

MemoryError

Problem installing fixture '/usr/local/django/myproject/fixtures/d20110727.py': Traceback (most recent call last):
  File "/var/snapshots/django/django/core/management/commands/loaddata.py", line 169, in handle
    for obj in objects:
  File "/var/snapshots/lino/lino/utils/dpy.py", line 352, in Deserializer
    module = imp.load_module(fqname, fp, fp.name, desc)
MemoryError

Nun ja, die Dump-Datei ist ein 6MB großes Python-Modul ohne Kommentare… und Jana ist eine virtuelle Maschine auf einem Proxmox-Server mit nur 512 MB Memory und 512 MB Swap. Es reichte, den Swap-Speicher auf 1024 zu erhöhen.

Aber es gibt also eine theoretische Grenze für dpy-Dumps: den Arbeitsspeicher. Falls das mal akut werden sollte, müsste man die Dump-Datei manuell in zwei Module teilen.

Automatische Tasks und lino.utils.dpy.Deserializer

Dann noch eine Überraschung:

INFO Deferred Task #436 (#436) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #437 (#437) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #438 (#438) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #439 (#439) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #440 (#440) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #441 (#441) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #442 (#442) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Deferred Task #443 (#443) : {'id': [u'Aufgabe mit diesem ID existiert bereits.']}
INFO Saved 0 instances.
WARNING Abandoning with 440 unsaved instances from t:\data\luc\lino\dsbe\fixtures\d20110727.py.
Problem installing fixture 't:\data\luc\lino\dsbe\fixtures\d20110727.py': Traceback (most recent call last):
  File "l:\snapshots\django\django\core\management\commands\loaddata.py", line 174, in handle
    obj.save(using=using)
  File "t:\hgwork\lino\lino\utils\dpy.py", line 288, in save
    "See dblog for details." % len(save_later))
Exception: Abandoned with 440 unsaved instances. See dblog for details.

Richtig, da hatte ich bisher nicht dran gedacht: beim Einlesen eines Dumps darf er nun nicht mehr automatische Tasks generieren. Deshalb die neue lino.utils.dpy.is_deserializing().

Noch kleine Wünsche

  • lino.modlib.jobs.models.Job ist jetzt par défaut nach ‘name’ sortiert (Meta.ordering). Checkin 20110727

  • Upps, das erste System mit is_deserializing zum Verhindern der automiatischen Tasks funktionierte zwar zum Laden des dumps, aber da war ein Denkfehler: es ist dann für alle Fixtures aktiv, auch für “intelligente” fixtures wie die demo. Es soll nur im Falle von dumps aktiv sein. Deshalb jetzt die neue globale Variable lino_xl.lib.cal.SKIP_AUTO_TASKS, die in lino.apps.dsbe.migrate.install() auf True gesetzt wird

  • Im Detail lino.modlib.jobs.models.Job fehlte noch die Kapazität.

Installation in Eupen um 9 Uhr gerade rechtzeitig zum Tagesbeginn, und somit erkläre ich Lino https://www.lino-framework.org/releases/2011/0727.html als released.

Another bug less in watch_tim

Noch ein subtiler Bug:

Traceback (most recent call last):
  File "/var/snapshots/lino/lino/apps/dsbe/management/commands/watch_tim.py", line 430, in watch
    process_line(i,ln)
  File "/var/snapshots/lino/lino/apps/dsbe/management/commands/watch_tim.py", line 403, in process_line
    m(**kw)
  File "/var/snapshots/lino/lino/apps/dsbe/management/commands/watch_tim.py", line 165, in PUT
    return self.POST(**kw)
  File "/var/snapshots/lino/lino/apps/dsbe/management/commands/watch_tim.py", line 298, in POST
    self.PUT(**kw)
  File "/var/snapshots/lino/lino/apps/dsbe/management/commands/watch_tim.py", line 165, in PUT
  ...
  File "/usr/lib/python2.6/copy.py", line 189, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/lib/python2.6/copy.py", line 322, in _reconstruct
    args = deepcopy(args, memo)
  File "/usr/lib/python2.6/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python2.6/copy.py", line 235, in _deepcopy_tuple
    y.append(deepcopy(a, memo))
  File "/usr/lib/python2.6/copy.py", line 192, in deepcopy
    _keep_alive(x, memo) # Make sure x lives at least as long as d
  File "/usr/lib/python2.6/copy.py", line 272, in _keep_alive
    memo[id(memo)].append(x)
KeyError: 31235952

Dieser Bug kam, wenn man in TIM in der PXS etwas änderte und diese Person in Lino nicht existierte (aus welchen Gründen auch immer). In so einem Fall bleibt Lino nichts anderes übrig, als die Information zu ignorieren, weil er den Namen der Person nicht kennt und sie folglich nicht implizit erstellen kann.

Lösung: siehe docstring von lino.apps.dsbe.management.commands.watch_tim.PXS.allow_put2post. Jetzt macht er in diesem Fall eine Warnung PXS:0000020475 : PUT ignored (row does not exist) statt eines Tracebacks.

Miscellaneous bugfixes

Das folgende Problem war ein echter kleine Bug:

  1. Stellenanfragen können momentan nicht erstellt werden. Grid ohne Detail reagiert nicht auf Doppelklick auf dem phantom record.

In Grids, die auch ein unformatiertes TextField enthielten, konnte man weder bearbeiten noch Zeilen einfügen, weil er dann fälschlicherweise versuchte, Ext.form.TextArea.refresh() aufzurufen.

Dann noch ein Problem, dessen Identifizierung allein einige Mühe gefordert hat:

  1. Wenn man über das Detail einer Stelle auf einen Vertrag in dieser Stelle geht und dort die Stelle ändert, dann kommt Lino durcheinander, weil er den Boden unter den Füßen weggezogen bekommen hat: ContractsByJob/123 existiert plötzlich nicht mehr. Er müsste dann automagisch nach Contracts/123 springen. Was voraussichtlich lediglich zur Folge hätte, dass die Navigationsbuttons prev/next/last/first deaktiviert würden. Oder das Feld “Stelle” sollte readonly sein, aber dann brauchen wir einen neuen Button, um z.B. von ContractsByJob/123 nach Contracts/123 springen zu können.

Erklärung und Lösung sind verblüffend einfach: Wenn man im Detail-Fenster einen Record so verändert, dass er aus der Liste verschwindet, dann merkt Lino das und springt auf den ersten Record der Liste zurück. Aber was passiert, wenn es keinen “ersten Record der Liste” mehr gibt, weil der verschwundene Record der Letzte der Liste war? Genau das oben Beschriebene. Dieses Verhalten ist schon seit eh und je da, aber offenbar ist der Fall noch nicht oft aufgetreten. Jetzt kommt dann der freundliche Hinweis “No more records to display. Detail window has been closed.”

Der Titel eines Detail-Fensters ist jetzt nicht mehr einfach nur unicode(elem), sondern “Listentitel » Element”. Also z.B. statt bisher “Max MUSTERMANN (97)” steht dort jetzt “Personen » Max MUSTERMANN (97)”

Die dummy_messages.py wurde schon seit Längerem zu früh geschrieben, so dass die Texte aus der linolib.js nicht drin waren. Behoben. Oder auch nicht. Erstmals richtig eigentlich erst am 2011-08-26.