initialization.py 3.18 KB
Newer Older
1
#
Grégory Wisniewski's avatar
Grégory Wisniewski committed
2
# Copyright (C) 2006-2010  Nexedi SA
3
#
4 5 6 7
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
8
#
9 10 11 12 13 14 15
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17

18
from neo import logging
19

20
from neo.storage.handlers import BaseMasterHandler
21 22 23 24
from neo import protocol

class InitializationHandler(BaseMasterHandler):

25
    def answerNodeInformation(self, conn):
26 27
        self.app.has_node_information = True

28
    def notifyNodeInformation(self, conn, node_list):
29
        # the whole node list is received here
30
        BaseMasterHandler.notifyNodeInformation(self, conn, node_list)
31

32
    def sendPartitionTable(self, conn, ptid, row_list):
33 34
        """A primary master node sends this packet to synchronize a partition
        table. Note that the message can be split into multiple packets."""
35
        self.app.pt.load(ptid, row_list, self.app.nm)
36

37
    def answerPartitionTable(self, conn, ptid, row_list):
38 39
        app = self.app
        pt = app.pt
40
        assert not row_list
41 42
        if not pt.filled():
            raise protocol.ProtocolError('Partial partition table received')
43
        logging.debug('Got the partition table :')
44
        self.app.pt.log()
45 46 47
        # Install the partition table into the database for persistency.
        cell_list = []
        for offset in xrange(app.pt.getPartitions()):
48
            assigned_to_me = False
49 50
            for cell in pt.getCellList(offset):
                cell_list.append((offset, cell.getUUID(), cell.getState()))
51 52 53 54 55 56 57
                if cell.getUUID() == app.uuid:
                    assigned_to_me = True
            if not assigned_to_me:
                logging.warning('drop data for partition %d' % offset)
                # not for me, delete objects database
                app.dm.dropPartition(app.pt.getPartitions(), offset)

58 59
        app.dm.setPartitionTable(ptid, cell_list)
        self.app.has_partition_table = True
60

61
    def notifyPartitionChanges(self, conn, ptid, cell_list):
62 63 64 65 66 67 68 69 70 71
        # XXX: This is safe to ignore those notifications because all of the
        # following applies:
        # - master is monothreaded (notifyPartitionChanges cannot happen
        #   between sendPartitionTable/answerPartitionTable packets), so
        #   receiving the whole partition table is atomic
        # - we first ask for node information, and *then* partition
        #   table content, so it is possible to get notifyPartitionChanges
        #   packets in between (or even before asking for node information).
        # - this handler will be changed after receiving answerPartitionTable
        #   and before handling the next packet
72
        logging.debug('ignoring notifyPartitionChanges during initialization')