Вызов удаленного API в ColdFusion иногда вызывает тайм-аут - PullRequest
2 голосов
/ 09 июня 2009

У меня есть функция на сайте моей компании, которая использует переменную cgi.remote_host для вызова API, предоставленного hostip.info , и возвращает страну происхождения. Вот как это должно работать:

  • функция находит страну из API,
  • выполняет запрос к нашей локальной базе данных, чтобы определить, какой сайт мы будем пересылать пользователь и
  • перенаправляет пользователя на соответствующий сайт.

Если по какой-либо причине мы не можем связать страну с одним из наших регионов, мы перенаправляем пользователя на сайт по умолчанию.

На самом деле происходит из-за того, что иногда наш сервер не может найти API, и мы получаем ошибку тайм-аута.

Это прокси функции, которую мы вызываем для получения территории:

<cffunction name="getGeoInfo" access="public" output="true" returntype="any" hint="call getGeoIP API and check country against DB">
    <cfargument name="IPAddress" required="yes" type="string" />

    <!--- Calling hostip API to get our Geo IP information --->
    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" method="get" result="geoIP" />

    <!--- Try to parse the file, if it can't parse, we don't create the variable --->
    <cftry>
        <cfset geoIPXML = xmlParse(geoIP.fileContent) />
    <cfcatch type="any" />
    </cftry>

    <!--- If variable was created, perform the function to get territory info --->
    <cfif isDefined("geoIPXML")>
        <cfset countryAbbrev = geoIPXML.HostipLookupResultSet['gml:featureMember']['hostip']['countryabbrev'].xmlText />

        <cfquery name="theTerritory" datasource="#request.dsource#">
            SELECT territory
            FROM countries
            WHERE countryCode = <cfqueryparam value="#countryAbbrev#" cfsqltype="cf_sql_varchar" />
        </cfquery>

        <!--- If no record was found, set locale to default --->
        <cfif theTerritory.recordcount EQ 0>
            <cfset returnLocale = "default" />
        <cfelse>
            <!--- Otherwise set it to territory found in DB --->
            <cfset returnLocale = theTerritory.territory />
        </cfif>
    <cfelse>
    <!--- if no XML file was returned, set locale to default --->
        <cfset returnLocale="default" />
    </cfif>

    <cfreturn returnLocale />
</cffunction>

Что мне здесь не хватает? Как мне изменить эту функцию, чтобы, если время ожидания http-запроса истекло, я по-прежнему возвращал значение по умолчанию?

Ответы [ 3 ]

6 голосов
/ 09 июня 2009

Завершение вызова <cfhttp> в <cftry>.

Кроме того, я хотел бы, чтобы блок catch просто возвращал defaultLocale, а не делал ничего, а затем проверял бы наличие geoIPXML.

<cftry>

    <cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" 
            method="get" 
            result="geoIP"
            throwOnError="yes" />
    <cfset geoIPXML = xmlParse(geoIP.fileContent) />

<cfcatch type="any">
   <cfreturn "default">
</cfcatch>

</cftry>
2 голосов
/ 11 июня 2009

Любой подход будет работать, но вместо того, чтобы заключить ваш вызов в блок try catch, вы можете установить

throwOnTimeout="false"

атрибут при вызове и не нужно вносить никаких других дополнительных изменений в ваш код. Возвращается структура cfhttp, которая будет содержать переменную fileContent, но будет заполнена значением «Timeout Connection». Попытка xmlParse не удастся, и тогда выполнение попадет в ваш блок catch. Я бы порекомендовал, как это сделал Патрик, для в вашем блоке catch, чтобы остальная часть вашей процедуры не выполнялась произвольно.

2 голосов
/ 09 июня 2009

Я не совсем уверен, что ваш тайм-аут предназначен только для http-вызова или для страницы в целом. CFHTTP имеет атрибут тайм-аута. Вы можете использовать это, чтобы предотвратить тайм-аут вашей страницы, если ваш HTTP-вызов истекает.

Используйте это с try / catch (как указал Патрик), чтобы вернуть результат по умолчанию.

...