ColdFusion 8 — вмешательство Application.cfc

У меня только что возникла странная проблема с веб-сайтом клиента, мой рабочий домен использовал мои настройки приложений для доменов разработки. Раньше у меня не было этой проблемы, и удаление cflock вокруг Application.dsn (среди других настроек) решило проблему.

Как уже упоминалось, у меня есть рабочий сайт *www.* и сайт разработки *dev.*, мой сайт разработки находится в подпапке рабочего сайта /dev/ и имеет свой собственный Application.cfc.

Мой первый вопрос: если у меня есть переменные в моей области приложения в папке dev, перезапишет ли это переменные области приложения в папке выше? Будет ли он считать его таким же масштабом? Если это так, то это может объяснить, в чем проблема, а если нет, то я в тупике.

Мой второй вопрос: как мне исправить cflock переменные области приложения в моем application.cfc? Должен ли я вообще этим заниматься?

Вот мой Application.cfc, буду очень признателен за совет:

<cfcomponent output="true">

<cfimport taglib="taglib" prefix="func">

<!---

        Check staging directory exists

--->

<cfset THIS.env = "staging">

<!---

        Set application vars

--->

<cfset THIS.applicationTimeout = createTimeSpan(0,0,0,0)>
<cfset THIS.sessionManagement="Yes">
<cfset THIS.clientManagement = true>
<cfset THIS.clientStorage = "cookie">
<cfset THIS.loginStorage = "cookie">
<cfset THIS.setDomainCookies = false>
<cfset THIS.setClientCookies = true>
<cfset THIS.scriptProtect = true>
<cfset THIS.secureJSON = true> <!--- Added 12.06.13 --->

<!---

        Check environment
        Set application name

--->

<cfif THIS.env EQ "staging">
    <cfset THIS.applicationName = "devenv">
    <cfset THIS.dsn = "devenv">
<cfelse>
    <cfset THIS.applicationName = "liveenv">
    <cfset THIS.dsn = "liveenv">
</cfif>

<cfif #cgi.HTTP_HOST# NEQ "localhost">
    <cfset THIS.dirpath = "http://#cgi.http_host#">
    <cfset THIS.componentPath = "cfcs.">
<cfelse>
    <cfset urlString = #mid(cgi.PATH_INFO, 2, 200)#>
    <cfset THIS.localhostFolderName = #spanexcluding(urlString, "/")#>
    <cfset THIS.dirpath = "http://localhost/#THIS.localhostFolderName#">
    <cfset THIS.componentPath = "#THIS.localhostFolderName#.cfcs.">
</cfif>
<cfset THIS.name = THIS.applicationName>
<cfset THIS.sessiontimeout = createtimespan(0,0,20,0)>
<cfset THIS.setClientCookies = true>
<cfset THIS.visitor = true>


<cffunction name="onApplicationStart" returntype="void">

    <cfset APPLICATION.name = THIS.applicationName>
    <cfset APPLICATION.dsn = THIS.dsn>
    <cfset APPLICATION.DSN = THIS.dsn>
    <cfset APPLICATION.dirpath = THIS.dirpath>
    <cfset APPLICATION.componentPath = THIS.componentPath>
    <cfif #cgi.HTTP_HOST# EQ "localhost">
        <cfset APPLICATION.localhostFolderName = THIS.localhostFolderName>
    </cfif>

    <!--- USED FOR PATHS AND URLS --->  

    <!--- Property image upload paths ---->
    <cfset APPLICATION.paths = StructNew()>

    <!---

            Check environment
            Set local root

    --->

    <cfif THIS.env EQ "staging">

        <cfset APPLICATION.paths.localRoot = "c:\websites\foobar.co.uk\dev\">

    <cfelse>

        <cfset APPLICATION.paths.localRoot = "c:\websites\foobar.co.uk\">

    </cfif>


    <cfset APPLICATION.paths.logs = APPLICATION.paths.localRoot & "logs\">
    <cfset APPLICATION.paths.logFile = APPLICATION.paths.logs & "site_log.txt">       
    <cfset APPLICATION.paths.property = StructNew()>
    <cfset APPLICATION.paths.property.image = APPLICATION.paths.localRoot & "images\property\">
    <cfset APPLICATION.paths.property.large = APPLICATION.paths.property.image & "large\">
    <cfset APPLICATION.paths.property.thumb = APPLICATION.paths.property.image & "thumbs\">
    <cfset APPLICATION.paths.property.cmsThumb = APPLICATION.paths.property.image & "thumbs\cms\">
    <cfset APPLICATION.paths.property.pdf = APPLICATION.paths.localRoot & "pdf\">
    <cfset APPLICATION.paths.property.pdfGenerated = APPLICATION.paths.property.pdf & "generated\">
    <cfset APPLICATION.newsUploadPath = APPLICATION.paths.localRoot & "images\news\">
    <cfset APPLICATION.articlesUploadPath = APPLICATION.paths.localRoot & "images\articles\">

    <cfset APPLICATION.articlesThumbsDir = "../images/articles/thumbs/">
    <cfset APPLICATION.articlesContentDir = "../images/articles/assets/">
    <cfset APPLICATION.articlesAssetsDir = "../articles/assets/">

    <!--- Site URLS ---->
    <cfset APPLICATION.urls = StructNew()>
    <cfset APPLICATION.urls.root = "http://" & CGI.server_name & "/">
    <cfset APPLICATION.urls.com = "com">
    <cfset APPLICATION.urls.tagLib = APPLICATION.urls.root & "taglib/">
    <cfset APPLICATION.urls.cms.tagLib = "http://" & CGI.server_name & ":" & CGI.server_port & "/admin/tagLib/">
    <cfset APPLICATION.RowsPerPage = 10>

    <!--- Property URLS --->
    <cfset APPLICATION.urls.property.pdf = APPLICATION.urls.root & "pdf/">
    <cfset APPLICATION.urls.property.image = APPLICATION.urls.root & "images/property/">
    <cfset APPLICATION.urls.property.large = APPLICATION.urls.root & "images/property/large/">
    <cfset APPLICATION.urls.property.thumb = APPLICATION.urls.root & "images/property/thumbs/">
    <cfset APPLICATION.urls.property.cmsThumb = APPLICATION.urls.root & "images/property/thumbs/cms/">
    <cfset APPLICATION.urls.news.image = APPLICATION.urls.root & "images/news/">
    <cfset APPLICATION.urls.articles.image = APPLICATION.urls.root & "images/articles/">

    <cflock scope="Application" timeout="5" type="Exclusive">

        <cfscript>

            /* Commonly used objects and queries */

            // DAOs 
            APPLICATION.propertyDAO = CreateObject("component", "cfcs.dataobjects.propertyDAO").init(APPLICATION.dsn);

            APPLICATION.propertyImageDAO = CreateObject("component", "cfcs.dataobjects.property_imageDAO").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyImageDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_imageDAO").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyLocationDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_locationDAO").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyTypeDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_typeDAO").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyTenureDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_tenureDAO").init(APPLICATION.dsn);     
            APPLICATION.propertyGroupDAO = CreateObject("component", "cfcs.dataobjects.property_groupDAO").init(APPLICATION.dsn);     

            // Gateways
            APPLICATION.propertyGateway = CreateObject("component", "cfcs.dataobjects.propertyGateway").init(APPLICATION.dsn);
            APPLICATION.propertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_imageGateway").init(APPLICATION.dsn); 
            APPLICATION.propertyToPropertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_to_property_imageGateway").init(APPLICATION.dsn);
            APPLICATION.propertyLocationGateway = CreateObject("component", "cfcs.dataobjects.property_locationGateway").init(APPLICATION.dsn);
            APPLICATION.propertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_imageGateway").init(APPLICATION.dsn);
            APPLICATION.propertyTypeGateway = CreateObject("component", "cfcs.dataobjects.property_typeGateway").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyTypeGateway = CreateObject("component", "cfcs.dataobjects.property_typeGateway").init(APPLICATION.dsn);
            APPLICATION.propertyTenureGateway = CreateObject("component", "cfcs.dataobjects.property_tenureGateway").init(APPLICATION.dsn);
            APPLICATION.propertyToPropertyTenureGateway = CreateObject("component", "cfcs.dataobjects.property_to_property_tenureGateway").init(APPLICATION.dsn);
            APPLICATION.partnerGateway = CreateObject("component", "cfcs.dataobjects.partnerGateway").init(APPLICATION.dsn);

            // Business Objects
            APPLICATION.propertyBO = CreateObject("component", "cfcs.businessobjects.propertyBO").init(APPLICATION.dsn);

            // Common queries
            APPLICATION.qPartners = APPLICATION.partnerGateway.getAllRecords();    
            APPLICATION.qPropertyTypes = APPLICATION.propertyTypeGateway.getAllRecords(); 
            APPLICATION.qPropertyTenures = APPLICATION.propertyTenureGateway.getAllRecords(); 
            APPLICATION.qPropertyMinMaxSize = APPLICATION.propertyGateway.getMinMaxSize();
            APPLICATION.qPropertyLocations = APPLICATION.propertyLocationGateway.getAllRecords();

        </cfscript>
    </cflock>
</cffunction>
<cffunction name="onSessionStart" returntype="void">
    <cflock scope="Session" timeout="5" type="Exclusive">       
        <cfscript>
            SESSION.propertySearchCriteria = CreateObject("component", "cfcs.beans.property_search_criteria").init();
            SESSION.propertySearch = CreateObject("component", "cfcs.beans.property_search").init(SESSION.propertySearchCriteria);
        </cfscript>    
    </cflock>
</cffunction>


person eb_dev    schedule 13.06.2013    source источник
comment
Могли ли они использовать одно и то же имя приложения? Если имя приложения одинаковое, они будут использовать одну и ту же область. С разными именами их быть не должно.   -  person Miguel-F    schedule 13.06.2013
comment
Возможно, когда я настраивал тест переменной live/dev env, они временно использовали одно и то же имя приложения. Это, безусловно, объяснило бы проблему. Что лучше всего настроить в Application.cfc для тестирования live/dev?   -  person eb_dev    schedule 13.06.2013
comment
Пока у них разные имена приложений, они будут рассматриваться как совершенно отдельные приложения. Так что я думаю, что ваша логика в порядке. Что касается блокировки этого блока кода, я думаю, что это тоже нормально. Я делаю то же самое в своих приложениях.   -  person Miguel-F    schedule 13.06.2013
comment
Я тоже, но технически вам не нужно блокировать переменные приложения внутри OnApplicationStart, если только вы не собираетесь вызывать этот метод вручную. Когда CF вызывает его, область приложения автоматически блокируется. Однако если вы вручную вызываете OnApplicationStart, CF не блокирует область приложения.   -  person Leigh    schedule 13.06.2013
comment
Спасибо за советы @Miguel-F   -  person eb_dev    schedule 14.06.2013


Ответы (2)


Почему вы меняете имя своего приложения в зависимости от среды, в которой оно находится? Это бессмысленно. Приложение по-прежнему остается одним и тем же приложением, независимо от того, находится ли оно в разработке, находится ли оно в стадии подготовки или разработки.

Точно так же и с исходным кодом. У вас есть свой сайт разработки на вашем действующем веб-сайте? Как это имеет смысл?

Я не знаю, что происходит с переменными вашего приложения, но они привязаны к имени приложения (this.name), а не к тому месту, где Application.cfc находится в структуре каталогов.

Я подозреваю, что ваш ноль applicationTimeout здесь мало помогает. В основном это означает, что ваше приложение на самом деле никогда не сохраняется ... оно будет истекать при каждом запросе. Это тоже не имеет смысла.

Вам не нужно <cflock> этот код в onApplicationStart(). ColdFusion разрешает выполнение только одного запроса onApplicationStart(): все остальные запросы будут поставлены в очередь до тех пор, пока он не будет завершен, когда приложение запустится, поэтому запросы в очереди даже не будут пытаться его запустить.

Я думаю, что ваша проблема, скорее всего, вызвана вашим плохим дизайном фреймворка приложения и этой странной вещью, которую вы делаете, имея dev и prod в одном дереве исходного кода (что бросает вызов всей логике).

Разберите свой исходный код, и проблема не возникнет.

person Adam Cameron    schedule 13.06.2013
comment
ColdFusion разрешает выполнение только одного запроса onApplicationStart() (на самом деле это не главная проблема, но ..) насколько я понимаю, это верно только тогда, когда он вызывается автоматически в ходе обычного запуска приложения. . Если вы вызываете его вручную, например, для сброса, он не является однопоточным автоматически. - person Leigh; 14.06.2013
comment
Верно. А вот еще один, который я сделал ранее: cfmlblog.adamcameron. я/2012/07/. Я не хотел запутывать вещи больше, чем это необходимо, бросая это выше. - person Adam Cameron; 14.06.2013
comment
Спасибо за подробный ответ @AdamCameron. В ответ на ваши вопросы я изменил имя приложения в зависимости от среды, в которой оно находится, чтобы я мог легко переключаться между работой и разработкой, и мне не нужно было хранить два файла Application.cfc, ясно сейчас это плохая идея, поэтому вернемся к двум App.cfcs. dev находится в том же дереве папок из-за ограничений хостинга. - person eb_dev; 14.06.2013

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

if ( YouAreHappy and YouKnowIt ) {
This.name = "ClapYourHands";
}
else {
This.name = "StompYourFeet"; 
}

В реальной жизни ваше условие if будет чем-то, что отличает живую среду от тестовой. cgi.http_host — хороший кандидат.

person Dan Bracuk    schedule 13.06.2013