'Yields nodes for a ring partition.
If the \'write_affinity\' setting is non-empty, then this will yield N
local nodes (as defined by the write_affinity setting) first, then the
rest of the nodes as normal. It is a re-ordering of the nodes such
that the local ones come first; no node is omitted. The effect is
that the request will be serviced by local object servers first, but
nonlocal ones will be employed if not enough local ones are available.
:param ring: ring to get nodes from
:param partition: ring partition to yield nodes for
:param policy: optional, an instance of
:class:`~swift.common.storage_policy.BaseStoragePolicy`
:param local_handoffs_first: optional, if True prefer primaries and
local handoff nodes first before looking elsewhere.'

def iter_nodes_local_first(self, ring, partition, policy=None, local_handoffs_first=False):

    policy_options = self.app.get_policy_options(policy)
    is_local = policy_options.write_affinity_is_local_fn
    if (is_local is None):
        return self.app.iter_nodes(ring, partition, policy=policy)
    primary_nodes = ring.get_part_nodes(partition)
    handoff_nodes = ring.get_more_nodes(partition)
    all_nodes = itertools.chain(primary_nodes, handoff_nodes)
    if local_handoffs_first:
        num_locals = policy_options.write_affinity_handoff_delete_count
        if (num_locals is None):
            local_primaries = [node for node in primary_nodes if is_local(node)]
            num_locals = (len(primary_nodes) - len(local_primaries))
        first_local_handoffs = list(itertools.islice((node for node in handoff_nodes if is_local(node)), num_locals))
        preferred_nodes = (primary_nodes + first_local_handoffs)
    else:
        num_locals = policy_options.write_affinity_node_count_fn(len(primary_nodes))
        preferred_nodes = list(itertools.islice((node for node in all_nodes if is_local(node)), num_locals))
        handoff_nodes = ring.get_more_nodes(partition)
        all_nodes = itertools.chain(primary_nodes, handoff_nodes)
    node_iter = itertools.chain(preferred_nodes, (node for node in all_nodes if (node not in preferred_nodes)))
    return self.app.iter_nodes(ring, partition, node_iter=node_iter, policy=policy)
