I have a group of CFC's that I access from two seperate Applicaiton scopes.
One /Application.cfc is in the Root.
The other Application is in /Admin/Application.cfc
The cfcs are in in /_cfc/
If I call a cfc (using createObject())from a page in (for example) /Admin/members/edit.cfm, does this cfc get it's Application scope from:
Application 1: /Application.cfc
or
Application 2: /Admin/Application.cfc
The calling page is under Application 2, but the CFC itself is under Application 1.
I hope I am making sense.
Thanks
Jason
Scopes are dependant on the context in which a cfc is instantiated and not its physical location.
So given your example a cfc that lives under Application1 instantiated from a template in Application2 will see the application scope from Application2
Application is dependant on the name. Thus if I had two applications with different names, thats 2 sets of application scope variables.
The name of the application is normally defined like this
<cfcomponent>
<cfset this.name = 'myApplication' />
....
Related
I have been having this issue lately with changing application variables. I set application variables on application start and and then have a file that calls ApplicationStop() for when I want to restart the application. This works fine on a dev environment.
The problem I'm having is on the live environment. I clear the cfcache and hit the applicationStop file. This works sometimes and sometimes it doesn't. Also, we have 2 live servers which are load-balanced, so I have to go through this procedure twice and sometimes it works on one but not the other.
EDIT:
Sorry I wasn't clear enough. The problem is that the values for the application variables are not changing when I change them on the application.cfc file.
In ember's blog post about 1.12 release, mentions an example using application.deferReadiness inside an instance initializer. However, it doesn't seem to be working. The first parameter to the initialize function doesn't have a deferReadiness method. Any ideas?
I think it's reasonable to post #tomdale explanation here as an answer.
#tomdale: "It's not possible to defer app readiness in an instance initializer, since by definition instance initializers are only run after the app has finished booting.
Sidebar on the semantics of application booting: "App readiness" (as in, deferReadiness() and advanceReadiness()) refers to whether all of the code for the application has loaded. Once all of the code has loaded, a new instance is created, which is your application.
To restate, the lifecycle of an Ember application running in the browser is:
Ember loads.
You create an Ember.Application instance global (e.g.
App).
At this point, none of your classes have been loaded yet.
As your JavaScript file is evaluated, you register classes on the
application (e.g. App.MyController = Ember.Controller.extend(…);)
Ember waits for DOM ready to ensure that all of your JavaScript
included via <script> tags has loaded.
Initializers are run.
If you need to lazily load code or wait for additional setup, you can call deferReadiness().
Once everything is loaded, you can call advanceReadiness().
At this point, we say that the Application is
ready; in other words, we have told Ember that all of the classes
(components, routes, controllers, etc.) that make up the app are
loaded.
A new instance of the application is created, and instance
initializers are run.
Routing starts and the UI is rendered to the
screen.
If you want to delay showing the UI because there is some runtime setup you need to do (for example, you want to open a WebSocket before the app starts running), the correct solution is to use the beforeModel/model/afterModel hooks in the ApplicationRoute. All of these hooks allow you to return a promise that will prevent child routes from being evaluated until they resolve.
Using deferReadiness() in an initializer is an unfortunate hack that many people have come to rely on. I call it a hack because, unlike the model promise chain in the router, it breaks things like error and loading substates. By blocking rendering in initializers, IMO you are creating a worse experience for users because they will not see a loading or error substate if the promise is slow or rejects, and most of the code I've seen doesn't have any error handling code at all. This leads to apps that can break with just a blank white screen and no indication to the user that something bad has happened."
See also discussion: https://github.com/emberjs/ember.js/issues/11247
SOME BACKGROUND:
I'm using onCFCRequest() to handle remote CFC calls separately from regular CFM page requests. This allows me to catch errors and set MIME types cleanly for all remote requests.
THE PROBLEM:
I accidentally set some of my remote CFC functions to public access instead of remote and realized that they were still working when called remotely.
As you can see below, my implementation of onCFCRequest() has created a gaping security hole into my entire application, where an HTTP request could be used to invoke any public method on any HTTP-accessible CFC.
REPRO CODE:
In Application.cfc:
public any function onCFCRequest(string cfc, string method, struct args){
cfc = createObject('component', cfc);
return evaluate('cfc.#method#(argumentCollection=args)');
}
In a CFC called remotely:
public any function publicFunction(){
return 'Public function called remotely!';
}
QUESTION:
I know I could check the meta data for the component before invoking the method to verify it allows remote access, but are there other ways I could approach this problem?
onCfcRequest() doesn't really create the security hole, you create the security hole by blindly running the method without checking to see if it's appropriate to do so first, I'm afraid ;-)
(NB: I've fallen foul of exactly the same thing, so I'm not having a go # you ;-)
So - yeah - you do need to check the metadata before running the method. That check is one of the things that CF passes back to you to manage in its stead when you use this handler, and has been explicitly implemented as such (see 3039293).
I've written up a description of the issue and the solution on my blog. As observed in a comment below I use some code in there - invoke() - that will only work on CF10+, but the general technique remains the same.
I've inherited a CF application that currently runs on Fusebox 4.
I'm noticing quite a high number of application scope time-outs within the CF Administrator, and I'm not 100% about locking and where cflock should be used.
<cflock scope="application" type="exclusive" timeout="30">
<cfinclude template="fusebox4.runtime.cfmx.cfm">
</cflock>
Right now I can see a cflock around the main fusebox file. My instinct is telling me that this really isn't a sound practise. Can anyone advise if this is incorrect for a Fusebox application?
I'm not sure there is anything IN fusebox.runtime.cfmx.cfm that requires a full application lock. You should check. When you lock the whole "application scope" for each request you are affecting a sort of single-threading for that file. In other words 2 requests cannot run this file at the same time. Since it's a general file for the framework this greatly affects your scalability. As Germann has suggested an application be used judiciously - typically once for the life of the application.
Meanwhile the specific file in question (fusebox4.runtime.cfmx.cfm) has lots of things in that are not related to the application. You can't run the framework without it... I would removed this lock and examine fusebox4.runtime.cfmx.cfm to try and determine why someone felt it necessary to lock the file to begin with.
One more thing. There is a "MODE" setting somewhere in fusebox that can be set to DEV or "PROD" (my memory may be faulty). It could be that you are set to DEV - in which case lots of things are happening under the hood that you want to avoid - chiefly that each request is reassembling files in the "parsed" directory with each request. So check that one too.
Locks around big/long chunks of code IS a bad practice. In this case it should be really called only once at application start (if you use Application.cfc put it in OnApplicationStart() method, if you are still on Application.cfm then put it inside applicationStart/restart if block).
I have writen a fastcGI application using C and C++
I have a free function that returns a string, if a specific environment variable has not been set. The function looks like this:
namespace
{
std::string getNameString()
{
char * datastr_ = getenv(MY_ENVAR.c_str());
if (datastr_)
return std::string(datastr_);
return DEFAULT_NAME;
}
};
I then carry out the following steps (in the order given below)
I have edited my /etc/environment and added the appropriate environment variable
I confirm that the variable has been set by typing printenv on the console
I stop and then start the apache daemon
When I debug my application, I find that the environment variable has not been set. I suspect that the environment under which the fastcgi application is running may different from the environment 'normal' applications run under.
Does anyone know how to retrieve environment variable in a fastcgi app?
I suspect that fastcgi processes are spawned in a "cleaned" environment by default, given your observations. Apache certainly provides a way of setting environment variables for fastcgi. This has the added bonus of being slightly less cryptic too (who expects a webservice to behave differently when /etc/environment is changed?), like this you keep "web config things" with "web config things".
You could look here http://httpd.apache.org/docs/current/env.html and try to set the env variable in the apache process. I have assumed latest apache version.