def _get_members_slots(self, name: str, role: 'PostgresqlRole', nofailover: bool,
                           can_advance_slots: bool) -> Dict[str, Dict[str, Any]]:
        """Get physical replication slots configuration for a given member.

        There are following situations possible:

            * If the ``nostream`` tag is set on the member - we should not have the replication slot for it
              on the current primary or any other member even if ``replicatefrom`` is set, because
              ``nostream`` disables WAL streaming.

            * PostgreSQL is 11 and newer and configuration allows retention of member replication slots. In this case
              we want to have replication slots for every member except the case when we have ``nofailover`` tag set.

            * PostgreSQL is older than 11 or configuration doesn't allow member slots retention. In this case we want:

                * On primary have replication slots for all members that don't have ``replicatefrom`` tag pointing
                  to the existing member.

                * On replica node have replication slots only for members which ``replicatefrom`` tag pointing to us.

        Will log an error if:

            * Conflicting slot names between members are found

        :param name: name of this node.
        :param role: role of this node, ``primary``, ``standby_leader``, or ``replica``.
        :param nofailover: ``True`` if this node is tagged to not be a failover candidate, ``False`` otherwise.
        :param can_advance_slots: ``True`` if ``pg_replication_slot_advance()`` function is available,
                                  ``False`` otherwise.

        :returns: dictionary of physical replication slots that should exist on a given node.
        """
        from ..postgresql.misc import PostgresqlRole

        if not global_config.use_slots:
            return {}

        # we always want to exclude the member with our name from the list,
        # also exclude members with disabled WAL streaming
        members = filter(lambda m: m.name != name and not m.nostream, self.members)

        def leader_filter(member: Member) -> bool:
            """Check whether provided *member* should replicate from the current node when it is running as a leader.

            :param member: a :class:`Member` object.

            :returns: ``True`` if provided member should replicate from the current node, ``False`` otherwise.
            """
            return member.replicatefrom is None or\
                member.replicatefrom == name or\
                not self.has_member(member.replicatefrom)

        def replica_filter(member: Member) -> bool:
            """Check whether provided *member* should replicate from the current node when it is running as a replica.

            ..note::
                We only consider members with ``replicatefrom`` tag that matches our name and always exclude the leader.

            :param member: a :class:`Member` object.

            :returns: ``True`` if provided member should replicate from the current node, ``False`` otherwise.
            """
            return member.replicatefrom == name and member.name != self.leader_name

        # In case when retention of replication slots is possible the `expected_active` function
        # will be used to figure out whether the replication slot is expected to be active.
        # Otherwise it will be used to find replication slots that should exist on a current node.
        expected_active = leader_filter if role in (PostgresqlRole.PRIMARY, PostgresqlRole.STANDBY_LEADER) \
            else replica_filter

        if can_advance_slots and global_config.member_slots_ttl > 0:
            # if the node does only cascading and can't become the leader, we
            # want only to have slots for members that could connect to it.
            members = [m for m in members if not nofailover or m.replicatefrom == name]
        else:
            members = [m for m in members if expected_active(m)]

        leader_patroni_version = self.leader and self.leader.member.patroni_version
        slots: Dict[str, int] = self.slots
        ret: Dict[str, Dict[str, Any]] = {}
        for member in members:
            slot_name = slot_name_from_member_name(member.name)
            lsn = slots.get(slot_name, 0)
            if member.replicatefrom or leader_patroni_version and leader_patroni_version < (4, 0, 0):
                # `/status` key is maintained by the leader, but `member` may be connected to some other node.
                # In that case, the slot in the leader is inactive and doesn't advance, so we use the LSN
                # reported by the member to advance replication slot LSN.
                # `max` is only a fallback so we take the LSN from the slot when there is no feedback from the member.
                lsn = max(member.lsn or 0, lsn)
            ret[slot_name] = {'type': 'physical', 'lsn': lsn, 'expected_active': expected_active(member)}
        slot_name = slot_name_from_member_name(name)
        ret.update({slot: {'type': 'physical'} for slot in self.status.retain_slots
                    if not nofailover and slot not in ret and slot != slot_name})

        if len(ret) < len(members):
            # Find which names are conflicting for a nicer error message
            slot_conflicts: Dict[str, List[str]] = defaultdict(list)
            for member in members:
                slot_conflicts[slot_name_from_member_name(member.name)].append(member.name)
            logger.error("Following cluster members share a replication slot name: %s",
                         "; ".join(f"{', '.join(v)} map to {k}"
                                   for k, v in slot_conflicts.items() if len(v) > 1))
        return ret
Get physical replication slots configuration for a given member.

        There are following situations possible:

            * If the ``nostream`` tag is set on the member - we should not have the replication slot for it
              on the current primary or any other member even if ``replicatefrom`` is set, because
              ``nostream`` disables WAL streaming.

            * PostgreSQL is 11 and newer and configuration allows retention of member replication slots. In this case
              we want to have replication slots for every member except the case when we have ``nofailover`` tag set.

            * PostgreSQL is older than 11 or configuration doesn't allow member slots retention. In this case we want:

                * On primary have replication slots for all members that don't have ``replicatefrom`` tag pointing
                  to the existing member.

                * On replica node have replication slots only for members which ``replicatefrom`` tag pointing to us.

        Will log an error if:

            * Conflicting slot names between members are found

        :param name: name of this node.
        :param role: role of this node, ``primary``, ``standby_leader``, or ``replica``.
        :param nofailover: ``True`` if this node is tagged to not be a failover candidate, ``False`` otherwise.
        :param can_advance_slots: ``True`` if ``pg_replication_slot_advance()`` function is available,
                                  ``False`` otherwise.

        :returns: dictionary of physical replication slots that should exist on a given node.
        
patroni/dcs/__init__.py