Translations/Specs/MessageSharing/Migration

Not logged in - Log In / Register

Message Sharing Migration

Part of the message sharing project.

Assumptions

Migration steps

Migration consists of these phases:

Code changes

To be landed before migration:

Note: When clearing is_current in validate_is_current, converge the TM that's having the flag cleared.

Merge POTMsgSets

At the end of this phase, TranslationMessages will still be mostly diverged, but they'll be sharing POTMsgSets.

This phase requires at least a freeze on imports.

It's best to go through this separately per Ubuntu release, and maybe once for everything else. We must stop imports for whatever product or distroseries we're merging, which we can do individually for each Ubuntu series.

Commit transactions after every equivalence class of POTemplates. Keep track of which ones are done, so we can restart etc.

Pseudocode:

def get_potmsgset_key(potmsgset):
    return (potmsgset.msgid_singular, potmsgset.msgid_plural, potmsgset.context)


def merge_potmsgsets(potemplates):
    # Sort potemplates from "most representative" to "least representative."
    potemplates.sort(cmp=template_precedence)

    representatives = {}
    subordinates = {}

    # Figure out representative potmsgsets and their subordinates.
    for template in potemplates:
        for potmsgset in template.potmsgsets:
            key = get_potmsgset_key(potmsgset)
            if key not in representatives: representatives[key] = potmsgset
            representative = representatives[key]
            if representative in subordinates: 
                subordinates[representative].append(potmsgset)
            else:
                subordinates[representative] = []

    for representative, potmsgsets in subordinates.iteritems():
        for subordinate in potmsgsets:
            merge_translationtemplateitems(subordinate, representative)

            for message in subordinate.translation_messages:
                if message.potemplate is None:
                    # Guard against multiple shared imported messages.
                    if message.is_imported:
                        imported = representative.getImportedMessage(message.language, message.variant, potemplate=None)
                        if imported is not None: message.is_imported = False
                    # Guard against multiple shared current messages.
                    if message.is_current:
                        current = representative.getCurrentMessage(message.language, message.variant, potemplate=None)
                        if current is not None: message.is_current = False
                message.potmsgset = representative
            subordinate.destroy()

Merge TranslationMessages

This phase operates only on TranslationMessage, and can be done at leisure.

Use TranslationMessage.converge() as defined above. Run it on all TranslationMessages in distroseries/productseries that have translation focus, then on all other series from most representative to least representative.

Pseudocode:

def merge_translationmessages(potemplates):
    # Sort potemplates from "most representative" to "least representative."
    potemplates.sort(cmp=template_precedence)

    for template in potemplates:
        for potmsgset in template:
            for message in potmsget.getAllTranslationMessages():
                message.converge()

Database constraints

Once the assumptions are fulfilled:

  • If we still have it, drop all constraints involving TranslationMessage.pofile.

After rolling out code changes:

After migration:

Checks

Some things we should check regularly after migration:

Translations/Specs/MessageSharing/Migration (last edited 2009-04-28 11:36:55 by jtv)