Expose whether total_size is the same as limit.

Allows telling user whether what he sees is the whole result set, or just
a limited sample of it.
Tell user when he is only viewing a sample of a larger object set.

Provide compatibility with non-upgraded products.
Also, update erp5_l10n_fr translation.
Work around poor UPDATE use of index.

UPDATE query is exected to use the existing index on (processing_node,
priority, date) both for WHERE and ORDER BY, as is expected from
EXPLAIN-ing the equivalent SELECT:

MariaDB [erp5]> explain select uid from message_queue WHERE processing_node=0 AND date <= '2013-06-06 22:22:49' ORDER BY priority, date LIMIT 1;
+------+-------------+---------------+------+----------------------------------------------------------+-------------------------------+---------+-------+-------+--------------------------+
| id   | select_type | table         | type | possible_keys                                            | key                           | key_len | ref   | rows  | Extra                    |
+------+-------------+---------------+------+----------------------------------------------------------+-------------------------------+---------+-------+-------+--------------------------+
|    1 | SIMPLE      | message_queue | ref  | processing_node_processing,processing_node_priority_date | processing_node_priority_date | 2       | const | 26622 | Using where; Using index |
+------+-------------+---------------+------+----------------------------------------------------------+-------------------------------+---------+-------+-------+--------------------------+

If it weren't using the index for ORDER BY, "Extra" would contain
"Using filesort".

Still, UPDATE behaves differently:

  # User@Host: user[user] @  [10.0.0.3]
  # Thread_id: 1635880  Schema: erp5  QC_hit: No
  # Query_time: 2.668405  Lock_time: 2.460698  Rows_sent: 0  Rows_examined: 49263
  # Full_scan: No  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
  # Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0
  SET TIMESTAMP=1370557446;
  UPDATE
    message_queue
  SET
    processing_node=12
  WHERE
    processing_node=0
    AND DATE <= '2013-06-06 22:24:04'
    ORDER BY
    priority, DATE
  LIMIT 1;

So change the UPDATE..SELECT pattern into a SELECT FOR UPDATE..UPDATE
pattern, so SELECT's correct execution plan is used.
Get rid of global_activity_buffer_lock.
Cache getPhysicalPath as a volatile attribute.
Avoid looking up portal_activities when creating a message.

It is (likely) already known to caller, is only used to look up an option
which is rarely enabled, and it turns out to be (relatively) expensive.
Make registerMessage check for duplicate registration.

isMessageRegistered duplicates work done in registerMessage, so it wastes
time when creating an activity (in the likely event the activity is not a
duplicate).
Replace __getattr__ + __[sg]etitem__ calls by a single __[sg]etattr__ call.

Also, provide one argument per line.
Also, avoid shadowing "id" built-in.
Declare __slots__ .

Also, inherit from "object" as __slots__ are a new-style-class feature.
Move some work out of Message.__init__ .

So that creating an ActiveWrapper (or Method) once and reusing it to spawn
several activities gets a larger speed-up.
Use single-underscore property prefix.

For easier debugging, so we don't have to know how python mangles
double-underscore properties, as introspection is reduced by __slots__
usage.
Suggested by Julien Muchembled <jm@nexedi.com>
WIP Reduce lock contention when reserving activities.

When reserving activities, all processing nodes fetch the same row set, and
try to update them. This serialises activity reservation, which limits
scalability.
This change creates blinders so that each processing node sees a
completely different set of activities, avoiding lock contention.

Those blinders can be seen as comb-shaped, with slits 20-uids-wide and
teeths (number_of_processing_nodes * 20)-uids wide.
The goal of the "20" factor is to keep neighbouring activities together, in
the intent of keeping reindexations of maybe-neighbouring objects together
to reduce ZEO pressure when reindexing.
The comb shape comes from the fact that it's expensive to divide a table
into even contiguous chunks (count(*) is expensive, and this requires
centralisation) and also because it does not bias average activity age seen
by all processing nodes.

Also, it does not strongly bind a processing node to a set of rows by
involving a time-based sliding, so given enough time all nodes will have
had the opportunity of seeing the whole table. This helps in the case where
a processing node is busy for a long time (or just shut down).
Remove the ability to upgrade catalog when installing a business template.

This is just too dangerous, because the reindexation needed to recover from
it can take a non-trivial amount of time on "real" sites.