/// <summary>
    /// Use heartbeat to keep the REST API listening after initialization,
    /// be sure to call from a thread and not the main thread
    /// </summary>
    void DoHeartbeat()
    {
        bool reconnect = false;

        if (null == _sApiChromaInstance)
        {
            //LogErrorOnMainThread("DoHeartbeat: ApiChromaInstance is null!");
            reconnect        = true;
            ConnectionStatus = RECONNECT_CHROMA_API_NULL;
            ThreadWaitForSecond();
        }
        else
        {
            //Uri uri = new Uri(_sApiChromaInstance.ApiClient.BasePath);
            //LogOnMainThread(string.Format("Monitoring Heartbeat {0}...", uri.Port));
            while (_sWaitForExit &&
                   null != _sApiChromaInstance)
            {
                DateTime timeout = DateTime.Now + TimeSpan.FromSeconds(5);
                try
                {
                    Thread thread = new Thread(new ThreadStart(() =>
                    {
                        try
                        {
                            // The Chroma API uses a heartbeat every 1 second
                            _sApiChromaInstance.Heartbeat();
                        }
                        catch (Exception /* ex */)
                        {
                            //Debug.LogError(string.Format("Failed to invoke action! {0}", ex));
                        }
                    }));
                    thread.Start();
                    while (_sWaitForExit &&
                           DateTime.Now < timeout &&
                           thread.IsAlive)
                    {
                        Thread.Sleep(0);
                    }
                    if (_sWaitForExit &&
                        timeout < DateTime.Now &&
                        thread.IsAlive)
                    {
                        //Debug.LogError("Heartbeat: Timeout detected!");
                        thread.Abort();
                        reconnect = true;
                    }
                }
                catch (Exception)
                {
                    //LogErrorOnMainThread("Failed to check heartbeat!");
                    reconnect        = true;
                    ConnectionStatus = RECONNECT_CHROMA_API_HEARTBEAT_FAILURE;
                    ThreadWaitForSecond();
                }
                if (timeout < DateTime.Now)
                {
                    //LogErrorOnMainThread("Timeout detected!");
                    reconnect        = true;
                    ConnectionStatus = RECONNECT_CHROMA_API_HEARTBEAT_TIMEOUT;
                    ThreadWaitForSecond();
                }
                if (reconnect)
                {
                    break;
                }

                //LogOnMainThread(string.Format("Monitoring Heartbeat {0}...", uri.Port));
                _sConnected      = true;
                _sConnecting     = false;
                ConnectionStatus = CONNECTED;
                ThreadWaitForSecond();
            }

            //LogOnMainThread(string.Format("Heartbeat {0} exited", uri.Port));
            _sConnected      = false;
            _sConnecting     = false;
            ConnectionStatus = NOT_CONNECTED;
            ThreadWaitForSecond();
        }

        if (reconnect)
        {
            ThreadWaitForSecond();
            if (_sWaitForExit)
            {
                RunOnMainThread(() =>
                {
                    if (_sWaitForExit)
                    {
                        Connect();
                    }
                });
            }
        }
    }