speed
May 04, 2010
New collective.funkload releases
I have recently released a new version of collective.funkload and collective.recipe.funkload. There is one major improvment - funkload recorder is now working properly with collective.funkload scripts.
Here @RedTurtle we are heavily using funkload for acceptance and benchmarking tests. We have started using it in 2008 just after Bristol Performance Sprint. We have found even more useful with buildout recipe. The only missing part was the recorder. It's built-in Funkload itself, but it was not enabled in the recipe. Well - now it is ;-)
/ If you want to know how to include funkload in buildout project - check my previous blog /
Starting a recorder is quite easy:
$ ./bin/funkload record -p 8080 MyTest
for full usage call:
$ ./bin/funkload record --help
This will start proxy on 8080 port and save all your browser requests to MyTest funkload scenario. Now open your browser, change proxy configuration to localhost:8080 and click-through test case. When you finish - stop the proxy with Ctrl-C. Funkload will generate a test_MyTest.py file and notify you where you can find it. It should be now collective.funkload compatible - you can lunch:
$ ./bin/funkload test /path/to/test_MyTest.py
To test it.
Another small improvement is a PloneFLTestCase. It extends default funkload test case, implementing two additional methods helping with Plone content creation. Right now instead of using this approach:
folder_portal_factory = self._browse(server_url + "/coreloadtests/Members/" + self.user_id +"/createObject?type_name=Folder",
method='get',
follow_redirect=False,
description = 'Get folder portal factory')
folder_edit_url = folder_portal_factory.headers.get('Location')
folder_id = folder_edit_url.split('/')[-2]
folder_created = self.post(folder_edit_url, params=[
['id', folder_id],
['title', 'folder'],
['description', ''],
['description_text_format', 'text/plain'],
['subject_existing_keywords:default:list', ''],
['last_referer', 'http://localhost:8080/coreloadtests/Members/' + self.user_id + '/view'],
['form_submit', 'Save']],
description="Post /coreloadtests/Members/user...280843853/atct_edit")
new_folder_id = folder_created.url.split('/')[-2]
you can just do:
new_folder_id = self.addContent(
server_url,
portal_type='Folder',
params=[['id', 'id'],
['title', 'testing title'],
['description', 'testing description'],
['description_text_format', 'text/plain'],
['form.submitted', '1'],
['last_referer', ''],
['form_submit', 'Save']],
description='Create folder')
It doesn't do much, but for sure it helps you keep you test case readable.
Oct 16, 2009
Fast content import
For one of our customers we have implemented a prototype for fast importing data to Plone. Instead of creating thousands of Archetype-based objects - we are creating only brains. Real objects will be created manually by users. The difference is huge.
The task was simple - import to Plone 36.000 documents (with all children it gives the total of 120.000 objects). Simply creating it using invokeFactory will take too much time (aprox. 14 hours). Why not create just brains and let users decide which document fully migrate? This is what we did.
We started with import script which creates brains in portal_catalog using directly catalog_object method:
pc = getToolByName(self.context, 'portal_catalog')
pc.catalog_object(dummy_object, dummy_object.path)
dummy_object is a simple python object with all metadata that we need later for portal_catalog query:
>>> pp dummy_object.__dict__
{'title': u'dummy title',
'id': u'simple_id',
'review_state': 'private',
'path': '/plone/importfolder/ToBeMigrated_simple_id'}
After lunching the script (it took 19 minutes) we had all the brains (36.000) in portal_catalog with proper metadata/index updated. Now we need to allow users to see them. So we created traverser for our importfolder:
def __bobo_traverse__(self, REQUEST, name):
if name.startswith('ToBeMigrated'):
view = getMultiAdapter((self, self.REQUEST), name='to_be_migrated')
view.setBrainId(name)
return view
return super(ImportFolder, self).__bobo_traverse__(REQUEST, name)
which returns a simple BrowserView with the brain.id. The view has a template which informs end-user that this document need to be migrated. If he decided to import it - system will start import process for selected brain.id.
The rest is pure Plone folder_contents view which lists my 'dummy' brains in import_folder (cause the path in the brain is correct). Simple and much faster ;-)
Aug 24, 2009
Ridurre il numero dei click: SpeedUpUI
Introduzione al primo di una serie di prodotti atti a velocizzare l'interfaccia di Plone, aumentando le funzionalità present in ogni pagina
Introduzione
L'idea che sta dietro al progetto nasce dalla "lentezza" di Plone in tutte quelle situazioni in cui è necessario effettuare data-entry massivo e/o ripetere molto spesso la stessa operazione.
Non si sta quindi parlando di rendere Plone più veloce (il Web è pieno di sanguinose discussioni a riguardo!) ma di rendere l'interfaccia più semplice. A volte bastano pochi accorgimenti.
Un esempio semplice, ma che fa capire quello che intendo è la PLIP 228 discussa per Plone 4. Si parla di ripristinare il menù a tendina "Aggiungi nuovo elemento" anche per i contenuti che non sono cartella (rimosso con l'avvento di Plone 2.5). I motivi che hanno portato alla sua rimozione sono tutto sommato buoni (legati all'usabilità dell'interfaccia) ma tutti si sono accorti quanto fosse più facile prima (leggasi "meno click e meno caricamenti") inserire più contenti in modo massivo.
Un'interfaccia più ricca è anche più potente, ma porta anche a svantaggi dovuti alla sua minore facilità. Qual'è il confine?
In questo caso, e nei casi di cui questa serie di prodotti vuole occuparsi, la questione è ovviamente un appesantimento dell'interfaccia che diventa meno semplice, meno chiara...
Ad ogni modo non è sempre sbagliato fornire (a chi la vuole) un'interfaccia più complessa, che magari necessita l'utente/redattore ad un addestramento maggiore, ma che può portare a anche a ridurre il numero di caricamenti.
Esempio numero 1: le briciole di pane
Cosa non va nelle briciole di pane di Plone? Ovviamente nulla!
Chiari, semplici, leggibili link che permettono di tornare velocemente ai contenitori del documento corrente...
Quando un utente usa le briciole di pane?
Un utente visitatore le usa per tornare al contenitore... nulla di più, e non ci si aspetta quindi che siano necessarie altre funzionalità.
Trovo il comportamento attuale un po' limitante invece per gli utenti redattori... questi possono voler tornare al contenitore/i per effettuare altre operazioni, che a mio parere possono essere:
- Modificare il contenuto
- Accedere alla vista dei contenuti della cartella
- Aggiungere nuovi elementi
redturtle.speedupui.pathbar
Il primo (e speriamo non l'ultimo) prodotto si occupa ovviamente della pathbar di Plone che non a caso ho portato come esempio.
SpeedUpUI Pathbar sostituisce la normale viewlet delle briciole di pane con una versione più complessa che offre un menù a tendina ai redattori, per effettuare le operazioni descritte sopra.
La versione 0.1.0dev non supporta ancora la gestione dell'aggiunta di nuovi elementi (ammettiamolo... probabilmente sarebbe la modifica più interessante... date tempo al tempo!) così come non c'è un effettivo controllo dei permessi (perché mostrare un link "modifica" se l'utente non ha effettivamente il permesso di farlo?), ma ha offerto comunque interessanti spunti per fare riflessioni...
Innanzi tutto l'elemento corrente delle briciole di pane non ha nessuna funzionalità avanzata. Se si vuole modificare il contenuto corrente Plone offre già un apposito comando.
Per quali contenuti poi mostrare la voce "Contenti" per visualizzare i contenuti della cartella?
In un primo momento verrebbe da pensare tutti. Ovviamente tutti gli elementi della pathbar tranne l'ultimo sono sicuramente contenitori. Ad ogni modo ci sono casi in cui il contenitore è stato scritto per non sembrare tale... L'unico esempio vivente che ho visto usare questa funzionalità è l'oggetto PoiIssue del gestore di segnalazioni Poi.
Gli oggetti di questo tipo utilizzano l'interfaccia INonStructuralFolder. L'uso di questa interfaccia viene utilizzato da Plone per capire se la cartella deve in effetti sembrare una cartella agli occhi dell'utente (deve avere una scheda per visualizzare i contenuti?).
Martin Aspeli ha scritto un vecchio tutorial ancora valido a riguardo.
La scelta è stata quindi quella di non mostrare il comando di visione dei contenuti per i contenuti INonStructuralFolder.
Conclusione
Il prodotto non è completo, forse migliorabile (di certo per quanto riguarda l'interfaccia mostrata) e probabilmente qualche altra buona funzionalità potrebbe essere implementata.
La scelta di usare un namespace di secondo livello speedupui nasce da un fatto preciso: ci sono altri "pezzi" del puzzle Plone che possono mostrare funzionalità aggiuntive che permettano di ridurre i caricamenti...
Un esempio?
Il navigatore...

