### Apache Airflow version

main (development)

### What happened

Airflow has `job_heartbeat_sec` (default 5) that was updated to 50 seconds in our environment. This caused 2 instances of triggerer process running for HA to keep updating triggerer_id since below query takes current time minus 30 seconds to query against the latest_heartbeat. This causes alive_triggerer_ids to return empty list since job_heartbeat_sec is more than 50 seconds and the current trigger running this query assigns the triggers to itself. This keeps happening moving triggers from one instance to another.

https://github.com/apache/airflow/blob/62a534dbc7fa8ddb4c249ade85c558b64d1630dd/airflow/models/trigger.py#L216-L223

### What you think should happen instead

The heartbeat calculation should have a value based on job_heartbeat_sec rather than 30 seconds hardcoded so that queries to check triggerer processes alive are adjusted as per user settings.

### How to reproduce

1. Change job_heartbeat_sec to 50 in airflow.cfg
2. Run 2 instances of triggerer.
3. Make an operator that uses `FileTrigger` with the file being absent or any other long running task.
4. Check triggerer_id for the trigger which keeps changing. 

### Operating System

Ubuntu

### Versions of Apache Airflow Providers

_No response_

### Deployment

Virtualenv installation

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [X] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

"""Type class for the trigger details dictionary."""
    task: asyncio.Task
    name: str
    events: int
class TriggerRunner(threading.Thread, LoggingMixin):
    """
    Runtime environment for all triggers.
    Mainly runs inside its own thread, where it hands control off to an asyncio
    event loop, but is also sometimes interacted with from the main thread
    (where all the DB queries are done). All communication between threads is
    done via Deques.
    """
    
    triggers: dict[int, TriggerDetails]
    
    trigger_cache: dict[str, type[BaseTrigger]]
    
    to_create: deque[tuple[int, BaseTrigger]]
    
    to_cancel: deque[int]
    
    events: deque[tuple[int, TriggerEvent]]
    
    failed_triggers: deque[tuple[int, BaseException]]
    
    stop: bool = False
    def __init__(self):