### Summary

Handlers included from other roles via role dependencies are not deduplicated properly in ansible-core 2.15.0. This behaviour is specific to 2.15.0 and doesn't seem to be documented anywhere.

### Issue Type

Bug Report

### Component Name

ansible-core

### Ansible Version

```console
$ ansible --version
ansible [core 2.15.0]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /tmp/ansible-test/lib64/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /tmp/ansible-test/bin/ansible
  python version = 3.11.2 (main, Apr  5 2023, 11:57:00) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/tmp/ansible-test/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True
```


### Configuration

```console
$ ansible-config dump --only-changed -t all
CONFIG_FILE() = None
```


### OS / Environment

AlmaLinux 8

### Steps to Reproduce

1. Create a "global" role with a handler:

```
# roles/global/handlers/main.yml
- name: a global handler
  debug:
    msg: "a global handler has been triggered"
  listen: "global handler"
```

2. Create two roles with tasks that notify this handler, define the "global" role as a dependency in both roles:

```
# roles/role1/meta/main.yml
dependencies:
  - global
```

```
# roles/role1/tasks/main.yml
- name: role1/task1
  debug:
  changed_when: true
  notify: "global handler"
```

```
# roles/role2/meta/main.yml
dependencies:
  - global
```

```
# roles/role2/tasks/main.yml
- name: role2/task1
  debug:
  changed_when: true
  notify: "global handler"
```

3. Create a playbook:

```
# playbook.yml
- hosts: localhost
  roles:
    - role1
    - role2
```

4. Resulting file tree:
```
.
├── playbook.yml
└── roles
    ├── global
    │   └── handlers
    │       └── main.yml
    ├── role1
    │   ├── meta
    │   │   └── main.yml
    │   └── tasks
    │       └── main.yml
    └── role2
        ├── meta
        │   └── main.yml
        └── tasks
            └── main.yml
```

5. Run the playbook with Ansible 2.15, verify that the handler has been invoked twice.

### Expected Results

Ansible 2.14 deduplicates the handler:

```
$ ansible-playbook --version
ansible-playbook [core 2.14.6]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /tmp/ansible-test/lib64/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /tmp/ansible-test/bin/ansible-playbook
  python version = 3.11.2 (main, Apr  5 2023, 11:57:00) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/tmp/ansible-test/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True
```

```
$ ansible-playbook playbook.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ****************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [localhost]

TASK [role1 : role1/task1] ******************************************************************************************************************************************************************
changed: [localhost] => {
    "msg": "Hello world!"
}

TASK [role2 : role2/task1] ******************************************************************************************************************************************************************
changed: [localhost] => {
    "msg": "Hello world!"
}

RUNNING HANDLER [global : a global handler] *************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "a global handler has been triggered"
}

PLAY RECAP **********************************************************************************************************************************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

```

Ansible 2.15 runs this handler twice (see actual results).

### Actual Results

```console
$ ansible-playbook playbook.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ****************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [localhost]

TASK [role1 : role1/task1] ******************************************************************************************************************************************************************
changed: [localhost] => {
    "msg": "Hello world!"
}

TASK [role2 : role2/task1] ******************************************************************************************************************************************************************
changed: [localhost] => {
    "msg": "Hello world!"
}

RUNNING HANDLER [global : a global handler] *************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "a global handler has been triggered"
}

RUNNING HANDLER [global : a global handler] *************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "a global handler has been triggered"
}

PLAY RECAP **********************************************************************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
}
                    
                    worker_prc = WorkerProcess(
                        self._final_q, task_vars, host, task, play_context, self._loader, self._variable_manager, plugin_loader, self._cur_worker,
                    )
                    self._workers[self._cur_worker] = worker_prc
                    self._tqm.send_callback('v2_runner_on_start', host, task)
                    worker_prc.start()
                    display.debug("worker is %d (out of %d available)" % (self._cur_worker + 1, len(self._workers)))
                    queued = True
                self._cur_worker += 1
                if self._cur_worker >= rewind_point:
                    self._cur_worker = 0
                if queued:
                    break
                elif self._cur_worker == starting_worker:
                    time.sleep(0.0001)
            self._pending_results += 1
        except (EOFError, IOError, AssertionError) as e:
            
            display.debug("got an error while queuing: %s" % e)
            return
        display.debug("exiting _queue_task() for %s/%s" % (host.name, task.action))
    def get_task_hosts(self, iterator, task_host, task):
        if task.run_once:
            host_list = [host for host in self._hosts_cache if host not in self._tqm._unreachable_hosts]
        else:
            host_list = [task_host.name]
        return host_list
    def get_delegated_hosts(self, result, task):