Repository: ossrs/srs
File: trunk/src/app/srs_app_source.cpp (C++)

Code before:
        return srs_error_wrap(err, "start exec failed");
    }
    srs_trace("vhost %s exec reload success", vhost.c_str());
    
    return err;
}

srs_error_t SrsOriginHub::create_forwarders()
{
    srs_error_t err = srs_success;
    
    if (!_srs_config->get_forward_enabled(req->vhost)) {
        return err;
    }
    
    srs_utime_t queue_size = _srs_config->get_queue_length(req->vhost);

    SrsConfDirective* conf = _srs_config->get_forward_backend(req->vhost);
    if (conf) {
        int count = conf->args.size();
        for (int i = 0; i < count; i++) {
            std::string backend_url = conf->args.at(i);

            // create forward by backend
            std::vector<std::string> urls;
            if ((err = SrsHttpHooks::on_forward_backend(backend_url, req, urls)) != srs_success) {
                // ignore
                srs_trace("get backend failed, %s", srs_error_desc(err).c_str());
                continue;
            }

            std::vector<std::string>::iterator it;
            for (it = urls.begin(); it != urls.end(); ++it) {
                std::string url = *it;

                // create forwarder by url
                SrsRequest* freq = new SrsRequest();
                SrsAutoFree(SrsRequest, freq);
                srs_parse_rtmp_url(url, freq->tcUrl, freq->stream);
                srs_discovery_tc_url(freq->tcUrl, freq->schema, freq->host, freq->vhost, freq->app, freq->stream, freq->port, freq->param);

                SrsForwarder* forwarder = new SrsForwarder(this);
                forwarders.push_back(forwarder);

                std::stringstream forward_server;
                forward_server << freq->host << ":" << freq->port;

                // initialize the forwarder with request.
                if ((err = forwarder->initialize(freq, forward_server.str())) != srs_success) {
                    return srs_error_wrap(err, "init forwarder");
                }

Review comment (bug):
1. If the Forward fails, it should directly return failure and let the streaming fail as well.
2. If you ignore err at this point, where err is an object, it will lead to a leak.

`TRANS_BY_GPT3`

Code after:
        return srs_error_wrap(err, "start exec failed");
    }
    srs_trace("vhost %s exec reload success", vhost.c_str());
    
    return err;
}

srs_error_t SrsOriginHub::create_forwarders()
{
    srs_error_t err = srs_success;
    
    if (!_srs_config->get_forward_enabled(req_->vhost)) {
        return err;
    }

    // For backend config
    // If backend is enabled and applied, ignore destination.
    bool applied_backend_server = false;
    if ((err = create_backend_forwarders(applied_backend_server)) != srs_success) {
        return srs_error_wrap(err, "create backend applied=%d", applied_backend_server);
    }

    // Already applied backend server, ignore destination.
    if (applied_backend_server) {
        return err;
    }

    // For destanition config
    SrsConfDirective* conf = _srs_config->get_forwards(req_->vhost);
    for (int i = 0; conf && i < (int)conf->args.size(); i++) {
        std::string forward_server = conf->args.at(i);
        
        SrsForwarder* forwarder = new SrsForwarder(this);
        forwarders.push_back(forwarder);
        
        // initialize the forwarder with request.
        if ((err = forwarder->initialize(req_, forward_server)) != srs_success) {
            return srs_error_wrap(err, "init forwarder");
        }

        srs_utime_t queue_size = _srs_config->get_queue_length(req_->vhost);
        forwarder->set_queue_size(queue_size);
        
        if ((err = forwarder->on_publish()) != srs_success) {
            return srs_error_wrap(err, "start forwarder failed, vhost=%s, app=%s, stream=%s, forward-to=%s",
                req_->vhost.c_str(), req_->app.c_str(), req_->stream.c_str(), forward_server.c_str());
        }
    }
    
    return err;
}