Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Why does openstack Nova use oslo_concurrency lockutils?

Hello,

I am checking Nova code these days, I found that Nova use oslo_concurrency lockutils as a decorator like @utils.synchronized(cell_mapping.uuid). for example

def set_target_cell(context, cell_mapping):
"""Adds database connection information to the context
for communicating with the given target_cell.

This is used for permanently targeting a cell in a context.
Use this when you want all subsequent code to target a cell.

Passing None for cell_mapping will untarget the context.

:param context: The RequestContext to add connection information
:param cell_mapping: An objects.CellMapping object or None
"""

global CELL_CACHE
if cell_mapping is not None:
    # avoid circular import
    from nova import db
    from nova import rpc

    # Synchronize access to the cache by multiple API workers.
    @utils.synchronized(cell_mapping.uuid)
    def get_or_set_cached_cell_and_set_connections():
        try:
            cell_tuple = CELL_CACHE[cell_mapping.uuid]
        except KeyError:
            db_connection_string = cell_mapping.database_connection
            context.db_connection = db.create_context_manager(
                db_connection_string)
            if not cell_mapping.transport_url.startswith('none'):
                context.mq_connection = rpc.create_transport(
                    cell_mapping.transport_url)
            CELL_CACHE[cell_mapping.uuid] = (context.db_connection,
                                             context.mq_connection)
        else:
            context.db_connection = cell_tuple[0]
            context.mq_connection = cell_tuple[1]

    get_or_set_cached_cell_and_set_connections()
else:
    context.db_connection = None
    context.mq_connection = None

the code above use @utils.synchronized(cell_mapping.uuid), I confused why we use lock here to synchronized global CELL_CACHE.

I thought Nova code only use coroutines and process. The coroutines will not cause race condition right? since coroutines context switch is not controlled by OS system.

The process use OS system to control context switch, but each process has it own memory addresses, global variable is not shared by each process, therefore it should not have any race condition here right?

Do I think something wrong? please help, thanks in advance.

Why does openstack Nova use oslo_concurrency lockutils?

Hello,

I am checking hacking Nova code these days, I found that Nova use oslo_concurrency lockutils as a decorator like @utils.synchronized(cell_mapping.uuid). for example

def set_target_cell(context, cell_mapping):
"""Adds database connection information to the context
for communicating with the given target_cell.

This is used for permanently targeting a cell in a context.
Use this when you want all subsequent code to target a cell.

Passing None for cell_mapping will untarget the context.

:param context: The RequestContext to add connection information
:param cell_mapping: An objects.CellMapping object or None
"""

global CELL_CACHE
if cell_mapping is not None:
    # avoid circular import
    from nova import db
    from nova import rpc

    # Synchronize access to the cache by multiple API workers.
    @utils.synchronized(cell_mapping.uuid)
    def get_or_set_cached_cell_and_set_connections():
        try:
            cell_tuple = CELL_CACHE[cell_mapping.uuid]
        except KeyError:
            db_connection_string = cell_mapping.database_connection
            context.db_connection = db.create_context_manager(
                db_connection_string)
            if not cell_mapping.transport_url.startswith('none'):
                context.mq_connection = rpc.create_transport(
                    cell_mapping.transport_url)
            CELL_CACHE[cell_mapping.uuid] = (context.db_connection,
                                             context.mq_connection)
        else:
            context.db_connection = cell_tuple[0]
            context.mq_connection = cell_tuple[1]

    get_or_set_cached_cell_and_set_connections()
else:
    context.db_connection = None
    context.mq_connection = None

the code above use @utils.synchronized(cell_mapping.uuid), I confused why we use lock here to synchronized global CELL_CACHE.

I thought Nova code only use coroutines and process. The coroutines will not cause race condition right? since coroutines context switch is not controlled by OS system.

The process use OS system to control context switch, but each process has it own memory addresses, global variable is not shared by each process, therefore it should not have any race condition here right?

Do I think something wrong? please help, thanks in advance.

Why does openstack Nova use oslo_concurrency lockutils?

Hello,

I am hacking Nova code these days, I found that Nova use oslo_concurrency lockutils as a decorator like @utils.synchronized(cell_mapping.uuid). for example

def set_target_cell(context, cell_mapping):
"""Adds database connection information to the context
for communicating with the given target_cell.

This is used for permanently targeting a cell in a context.
Use this when you want all subsequent code to target a cell.

Passing None for cell_mapping will untarget the context.

:param context: The RequestContext to add connection information
:param cell_mapping: An objects.CellMapping object or None
"""

global CELL_CACHE
if cell_mapping is not None:
    # avoid circular import
    from nova import db
    from nova import rpc

    # Synchronize access to the cache by multiple API workers.
    @utils.synchronized(cell_mapping.uuid)
    def get_or_set_cached_cell_and_set_connections():
        try:
            cell_tuple = CELL_CACHE[cell_mapping.uuid]
        except KeyError:
            db_connection_string = cell_mapping.database_connection
            context.db_connection = db.create_context_manager(
                db_connection_string)
            if not cell_mapping.transport_url.startswith('none'):
                context.mq_connection = rpc.create_transport(
                    cell_mapping.transport_url)
            CELL_CACHE[cell_mapping.uuid] = (context.db_connection,
                                             context.mq_connection)
        else:
            context.db_connection = cell_tuple[0]
            context.mq_connection = cell_tuple[1]

    get_or_set_cached_cell_and_set_connections()
else:
    context.db_connection = None
    context.mq_connection = None

the code above use @utils.synchronized(cell_mapping.uuid), I confused why we use lock here to synchronized global CELL_CACHE.

I thought Nova code only use coroutines and process. The coroutines will not cause race condition right? since coroutines context switch is not controlled by OS system.

The process use OS system to control context switch, but each process has it own memory addresses, global variable is not shared by each process, therefore it should not have any race condition here right?

Do I think something wrong? please help, thanks in advance.advance

Why does openstack Nova use oslo_concurrency lockutils?

Hello,

I am hacking Nova code these days, I found that Nova use oslo_concurrency lockutils as a decorator like @utils.synchronized(cell_mapping.uuid). for example

def set_target_cell(context, cell_mapping):
"""Adds database connection information to the context
for communicating with the given target_cell.

This is used for permanently targeting a cell in a context.
Use this when you want all subsequent code to target a cell.

Passing None for cell_mapping will untarget the context.

:param context: The RequestContext to add connection information
:param cell_mapping: An objects.CellMapping object or None
"""

global CELL_CACHE
if cell_mapping is not None:
    # avoid circular import
    from nova import db
    from nova import rpc

    # Synchronize access to the cache by multiple API workers.
    @utils.synchronized(cell_mapping.uuid)
    def get_or_set_cached_cell_and_set_connections():
        try:
            cell_tuple = CELL_CACHE[cell_mapping.uuid]
        except KeyError:
            db_connection_string = cell_mapping.database_connection
            context.db_connection = db.create_context_manager(
                db_connection_string)
            if not cell_mapping.transport_url.startswith('none'):
                context.mq_connection = rpc.create_transport(
                    cell_mapping.transport_url)
            CELL_CACHE[cell_mapping.uuid] = (context.db_connection,
                                             context.mq_connection)
        else:
            context.db_connection = cell_tuple[0]
            context.mq_connection = cell_tuple[1]

    get_or_set_cached_cell_and_set_connections()
else:
    context.db_connection = None
    context.mq_connection = None

the code above use @utils.synchronized(cell_mapping.uuid), I confused why we use lock here to synchronized global CELL_CACHE.

I thought Nova code only use coroutines and process. The coroutines will not cause race condition right? since coroutines context switch is not controlled by OS system.

The process use OS system to control context switch, but each process has it own memory addresses, global variable is not shared by each process, therefore it should not have any race condition here right?

Do I think something wrong? please help, thanks in advanceadvance.

Why does openstack Nova use oslo_concurrency lockutils?

Hello,

I am hacking Nova code these days, I found that Nova use oslo_concurrency lockutils as a decorator like @utils.synchronized(cell_mapping.uuid). for example

def set_target_cell(context, cell_mapping):
"""Adds database connection information to the context
for communicating with the given target_cell.

This is used for permanently targeting a cell in a context.
Use this when you want all subsequent code to target a cell.

Passing None for cell_mapping will untarget the context.

:param context: The RequestContext to add connection information
:param cell_mapping: An objects.CellMapping object or None
"""

global CELL_CACHE
if cell_mapping is not None:
    # avoid circular import
    from nova import db
    from nova import rpc

    # Synchronize access to the cache by multiple API workers.
    @utils.synchronized(cell_mapping.uuid)
    def get_or_set_cached_cell_and_set_connections():
        try:
            cell_tuple = CELL_CACHE[cell_mapping.uuid]
        except KeyError:
            db_connection_string = cell_mapping.database_connection
            context.db_connection = db.create_context_manager(
                db_connection_string)
            if not cell_mapping.transport_url.startswith('none'):
                context.mq_connection = rpc.create_transport(
                    cell_mapping.transport_url)
            CELL_CACHE[cell_mapping.uuid] = (context.db_connection,
                                             context.mq_connection)
        else:
            context.db_connection = cell_tuple[0]
            context.mq_connection = cell_tuple[1]

    get_or_set_cached_cell_and_set_connections()
else:
    context.db_connection = None
    context.mq_connection = None

the code above use @utils.synchronized(cell_mapping.uuid), I confused why we use lock here to synchronized global CELL_CACHE.

I thought Nova code only use coroutines and process. The coroutines will not cause race condition right? since coroutines context switch is not controlled by OS system.

The process use OS system to control context switch, but each process has it own memory addresses, global variable is not shared by each process, therefore it should not have any race condition here right?

Do I think something wrong? please help, thanks in advance.