Global State / Configuration Models In Rails - ruby-on-rails-4

I have a set of configuration variables (not environment specific) that need to be wrapped in a class that exposes them to the rest of the application. If all I wanted to expose was the values, I could load them via a YAML file / expose on the Rails config object, however I want the class to offer a simple API that combines / manipulates these pieces of data. This data will never change after initialisation, but needs to be used in numerous places. Storing it in the database seems like unnecessary complexity.
I initially experimented with storing state on a class and accessing it via class methods: Example.getter, but this is problematic in development due to class reloading blowing away the state. The same is true for Singletons.
Another alternative is storing them on an instance of a class, but where should that instance live? I could add it to the Rails config object and access it there, but using the config object as some kind of registry doesn't feel right: Rails.application.config.example.getter and is very verbose.
How should I store this kinds of configuration so it is easy to access from within the application?

Related

Django: Making sure a complex object is accessible throughout multiple view calls

for a project, I am trying to create a web-app that, among other things, allows training of machine learning agents using python libraries such as Dedupe or TensorFlow. In cases such as Dedupe, I need to provide an interface for active learning, which I currently realize through jquery based ajax calls to a view that takes and sends the necessary training data.
The problem is that I need this agent object to stay alive throughout multiple view calls and be accessible by each individual call. I have tried realizing this via the built-in cache system using Memcached, but the serialization does not seem to keep all the info intact, and while I am technically able to restore the object from the cache, this appears to break the training algorithm.
Essentially, I want to keep the object alive within the application itself (rather than an external memory store) and be able to access it from another view, but I am at a bit of a loss of how to realize this.
If someone knows the proper technique to achieve this, I would be very grateful.
Thanks in advance!
To follow up with this question, I have since realized that the behavior shown seemed to have been an effect of trying to use the result of a method call from the object loaded from cache directly in the return properties of a view. Specifically, my code looked as follows:
#model is the object loaded from cache
#this returns the wrong object (same object as on an earlier call)
return JsonResponse({"pairs": model.uncertain_pairs()})
and was changed to the following
#model is the object loaded from cache
#this returns the correct object (calls and returns the model.uncertain_pairs() method properly)
uncertain = model.uncertain_pairs()
return JsonResponse({"pairs": uncertain})
I am unsure if this specifically happens due to an implementation from Dedupe or Django side or due to Python, but this has undoubtedly fixed the issue.
To return back to the question, Django does seem to be able to properly (de-)serialize objects and their properties in cache, as long as the cache is set up properly (see Apparent bug storing large keys in django memcached which I also had to deal with)

Ember JS automatically register directory classes to DI

Creating in-repo-addon in Ember.JS gives a lot of possibilities. Today I've stumbled into a case when I wanted to register all classes in directory (for example my-dir) into Dependency Injector (same way it's done with services by Ember, but I wanted to use some other namespace).
For example I want to allow developer to create multiple classes inside proxy directory, and register all of them in DI under proxy: namespace. So later we can use:
Ember.Component.extend({
myProxy: Ember.inject('proxy:my'),
});
You'll need to do this using an initializer. More details on this here: https://guides.emberjs.com/v2.12.0/applications/dependency-injection/
The hard part may be getting all proxy items in s folder to automatically register ...
Edit
Looks like I didn't spend enough time thinking about this. You should be able to do at least part of this easily. There are two parts to this.
Part 1
Ember currently uses the ember-resolver to handle lookups for various items. If you check the tests for the resolver you'll notice that you should be able to map in anything you want: https://github.com/ember-cli/ember-resolver/blob/master/tests/unit/resolvers/classic/basic-test.js
So in your case, if you do a Ember.getOwner(this).lookup('proxy:main') from within an Ember instantiated class (a route, controller or component for instance) it would look in app/proxy/main.js which your addon could be populating.
Details on the Ember.getOwner lookup are available here: https://emberjs.com/api/classes/Ember.html#method_getOwner
Part 2
So at this point you can lookup proxies (which would be doable in an init method). But if we want to get truly elegant we'd want to allow Ember.inject.proxy('main') syntax.
Doing so would involve calling a private method inside of Ember.inject in an initializer. Because that naming scheme is changing in the new Javascript modules RFC, it may be unwise to try to add this syntactic sugar ...
So I'd advise avoiding touching that private API unless it's really important to your app design.

In Component, what's the best pattern for creating configuration at system-start?

There's a pattern I haven't figured out for Component yet:
I have some "live" configuration that requires disk IO (a component) on system-start, and has a dependency on a map of static config (.edn), and after this "live" configuration is instantiated, it won't change or side-effect anything anymore.
For ex: I need to set this up once, and it depends on static config:
(buddy.core.backends/jws
{:secret (buddy.core.keys/public-key
path-to-public-key-from-static-config)})
I would then reuse that backend ad-infinitum, (ex: in buddy.auth.middleware/wrap-authentication), and it doesn't change, nor side-effect.
Possible Solutions
I could make a component that stores this backend at system-start. But this gives up generality, because when I want to add similar "live config", it would have to be explicitly written into the component, and that gives up the spirit of generality that I think Component champions (eg Duct says components define side-effects, and create boundaries to access them)
I could pass a generic component a map of keys - [fn & args] and the fn+args get evaluated and stored in the component. But this feels like it offloads computation to my configuration .edn, and is an anti-pattern. For example:
(private-key priv-path-from-static
(slurp :password-path-from-static))
Should I encode the notion of slurping in my .edn config? I don't want to offload computation to a config file...
The backend and keys can be instantiated on a per-need basis within each component that requires them. IMO, that's too much of computing the exact same thing, when I'd rather it be stored in memory once.
I could have an atom component that holds a map of these "live" config objects, but then they get destructively added in, and my code has lost it's declarative nature.
TL;DR
What's the best way to create configuration at system-start, possibly needing dependencies, and then becoming available to other components as a component, while not giving up the generality which components should have?
In an ideal world, I think the component itself should describe what type of configuration data it needs. (This could be done with a protocol extending the component in question.). When the config component is started, it should look at all other components, get the list of config requirements and resolve it somehow (from a file, a database, etc.).
I've not seen such a library, but Aviso's config library comes close, maybe you can adapt it to your needs.

Why do we need to create an instance of a CFC?

I'm using the CreateObject() method to create an instance of a CFC and then interacting with this newly created 'instance'. I'm doing this because that's how it seems to be done, but I don't understand why we do this.
Why can't we just interact with the CFC directly instead of creating an instance of it?
A CFC is just a file with some code in it, so it makes little sense to suggest "interacting" with it, just the same as you might suggest "interacting" with a CFM file without <cfinclude>-ing it or similar.
A CFC defines a component, and to use a component, one creates an instance of it. In some languages - eg Java - one can have static properties and methods, and one can access them via the class rather than necessarily object, but CFML does not have this concept. CFCs define components which are used as objects, just the same as in other languages a class defines what it is to be an object, and to use an object, one first needs to create an instance of it.
You can call the cfc directly using cfinvoke. You just have to realize that cfinvoke creates an object of the cfc first, then executes the method you invoked. Also, once the method is invoked, the object is no longer available.
If your .cfm page is only going to use one method of the component, cfinvoke is ok because there is less code for you to write. However, if you use two or more, it's less efficient because a new object has to be created each time.
In other word, while you don't have to create an instance of the cfc first, it's often a good idea to do so.
I hope you have read OOPs and its practices. CFC is your 'blueprint' (say a car design) and object is your own data model (say a car of blue color (method to set color), with nitrogen filled tires (method to set pressure in tires) and runs on LPG (method for fuel type)). CF allow you interact directly with CFC (CFINVOKE) and you do not have to create an instance each time but it just only make sense that you would not want to go to workshop/design lab each time you want to change a configuration for your car.

Ember-CLI - How to access application classes

Previously when I developed ember application I used App as my global object and every class was stored in this big object.
Like this
window.App.MyModel = Em.Object.extend({});
And in the browser console, I was able to do
App.MyModel.create();
So it was really easy for me to access MyModel class.
Now I started experiments with Ember-CLI, I don't have much experience with this kind of tools. I followed the documentations and I created my model Service like this.
var Service = Ember.Object.extend({});
export default Service
But now, how to access Service class from browser console?
Only way I found was:
App.__container__.resolve('model:service')
But I don't like it much. Is there better way? Btw, can you please explain how export works? Or is there some source (documentation, article) where I can study it?
Thanks a lot for response.
If you're aiming to have something available in most places throughout your application you'll typically want to register it on the container.
There are multiple ways to access the container, and you're correct in that the one you found was less than ideal. The running joke is "any time you directly access __container__ we need to add more underscores."
To directly control how things are registered on the container and injected into the container you typically want to use an initializer. Using initializers in ember-cli is super-easy, they're executed for you automatically.
Checking out the documentation you can see that you get access to the application's container as an argument which allows you to manipulate it in a safe manner.
Once you have access to the container you can use register and inject to make content easily available in particular locations. This was introduced here. One note, accessing things inside of the container from outside the context of your app (browser console) will require the usage of App.__container__ and that is the expected use pattern.
And the export you're running into is an ES6 module system construct, it's not Ember-specific. Playing with the ES6 module transpiler can give you a good sense of what goes in and what comes out in "we can do this today" type of JavaScript.
For ember 3.22, application classes can be accessed like so:
Ember.Namespace.NAMESPACES[1]._applicationInstances.values().next().value.lookup('service:state-events')
Note, you may need to modify the index in NAMESPACES[1] to be something other than 1. You can determine which namespace is your application when this returns true:
Ember.Namespace.NAMESPACES[1] instanceof Application
This approach is how ember-inspector accesses ember applications: https://github.com/emberjs/ember-inspector/blob/50db91b7bd26b12098cae774a307208fe0a47d75/ember_debug/main.js#L163-L168