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

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.

Related

Repository pattern: isn't getting the entire domain object bad behavior (read method)?

A repository pattern is there to abstract away the actual data source and I do see a lot of benefits in that, but a repository should not use IQueryable to prevent leaking DB information and it should always return domain objects, not DTO's or POCO's, and it is this last thing I have trouble with getting my head around.
If a repository pattern always has to return a domain object, doesn't that mean it fetches way too much data most of the times? Lets say it returns an employee domain object with forty properties and in the service and view layers consuming that object only five of those properties are actually used.
It means the database has fetched a lot of unnecessary data a pumped that across the network. Doing that with one object is hardly noticeable, but if millions of records are pushed across that way and a lot of of the data is thrown away every time, is that not considered bad behavior?
Yes, when adding or editing or deleting the object, you will use the entire object, but reading the entire object and pushing it to another layer which uses only a fraction of it is not utilizing the underline database and network in the most optimal way. What am I missing here?
There's nothing preventing you from having a separate read model (which could a separately stored projection of the domain or a query-time projection) and separating out the command and query concerns - CQRS.
If you then put something like GraphQL in front of your read side then the consumer can decide exactly what data they want from the full model down to individual field/property level.
Your commands still interact with the full domain model as before (except where it's a performance no-brainer to use set based operations).

Glimmer.js how to reset tracked property to initial value without using the constructor

In Glimmer.js, what is the best way to reset a tracked property to an initial value without using the constructor?
Note: Cannot use the constructor because it is only called once on initial page render and never called again on subsequent page clicks.
There are two parts to this answer, but the common theme between them is that they emphasize switching from an imperative style (explicitly setting values in a lifecycle hook) to a declarative style (using true one-way data flow and/or using decorators to clearly indicate where you’re doing some kind of transformation of local state based on arguments).
Are you sure you need to do that? A lot of times people think they do and they should actually just restructure their data flow. For example, much of the time in Ember Classic, people reached for a pattern of "forking" data using hooks like didInsertElement or didReceiveAttrs. In Glimmer components (whether in Ember Octane or in standalone Glimmer.js), it's idiomatic instead to simply manage your updates in the owner of the data: really doing data-down-actions-up.
Occasionally, it does actually make sense to create local copies of tracked data in a component—for example, when you want to have a clean separation between data coming from your API and the way you handle data in a form (because user interfaces are API boundaries!). In those scenarios, the #localCopy and #trackedReset decorators from tracked-toolbox are great solutions.
#localCopy does roughly what its name suggests. It creates a local copy of data passed in via arguments, which you can change locally via actions, but which also switches back to the argument if the argument value changes.
#trackedReset creates some local state which resets when an argument updates. Unlike #localCopy, the state is not a copy of the argument, it just needs to reset when the argument updates.
With either of these approaches, you end up with a much more “declarative” data flow than in the old Ember Classic approach: “forking” the data is done via decorators (approach 2), and much of the time you don’t end up forking it at all because you just push the changes back up to the owner of the original data (1).

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.

Clojure - component and names

I am trying to understand Stuart Sierra's component, specifically the naming convention for the components in order to structure a Clojure application.
If I look into system for instance, I see several components mapped to the :server key :
aleph
immutant
Since both use the same key :server, does that mean that I can only use one of them if I use this library ?
Similarly, I use onyx. Several components are already defined inside onyx system.clj.
Does that mean that some keys are effectively reserved by onyx ?
What will happen to the :port parameter, which seems to be used by many components in the wild ?
Questions
What is get the difference between the keys used when associng in the start method and the keys used in component/system-map ?
Is there a naming convention for those keys, how do we avoid collisions between those keys ?
In which cases (if any) does it make sense to have several systems and can they run at the same time ?
Keys in the system map identify specific components (instances) in that system. You can use whatever key you like for whatever component you need.
Keys in a specific component record can be one of three things:
a configuration value set up at creation time
some internal value that is irrelevant to the user of the component
a dependency (which will refer to another component when the system is started)
1 and 2 are generally set up by the component constructor and users do not need care about the actual key used in the record.
Dependencies are configured by setting a mapping on the depending component from the dependency key (3) to the key in the system map referring to the dependancy component. This is done with the component/using function and giving it a map of component keys to system-map keys as the second argument. That way you can always map any expected key to any actually used key. You can use the short-hand form of component/using with a vector of keys, but only if the keys in the system-map are the same as the keys in the component you're configuring.
I hope that answers the first two questions
The third question I think I'd like to see an example of what you're looking for as a separate post
The last question: yes you can have multiple systems running at the same time. That may or may not make sense depending on what you want to do, but running a test system as well as a development system seems like a fairly obvious setup.

Ember-Router: dynamically create state from a recursive path

I need a way for ember router to route to a recursive path.
For Example:
/:module
/:module/:submodule
/:module/:submodule/:submodule
/:module/:submodule/:submodule/...
Can this be done with Embers router, and if so, how?
I've been looking for examples, tearing apart the source, and I've pretty much come to the conclusion, it's not possible.
In a previous question, someone had pointed me to a way to get the url manually and split it, but I'm stuck at creating the state for the router to resolve to.
As of now, in my project, I currently just use the Ember.HashLocation to setup my own state manager.
The reason for the need of this, is because the module definitions are stored in a database, and at any given point a submodule of a submodule, recursively, could be added. So I'm trying to make the Application Engine handle the change.
Do your submodules in the database not have unique IDs? It seems to me that rather than representing your hierarchy in the path, you should just go straight to the appropriate module or submodule. Of course the hierarchy is still in your data model, but it shouldn't have to be represented in your routing scheme. Just use:
/module/:moduleId
/submodule/:submoduleId
And don't encode the hierarchy in the routes. I understand it might be natural to do so, but there's probably not a technical reason to.
If your submodules don't have unique ids, it's maybe a little tougher...you could build a unique ID by concatenating the ancestor ids together (say, with underscores), which is similar to splitting the URL, but a little cleaner probably. I will say that Ember/Ember Data doesn't seem to be too easy to use with entities with composite keys--if everything has a simple numeric key everything becomes easier (anyone want to argue with me on this, please explain to me how!).
DO you mean like this:
App.Router.map(function(match) {
match('/posts').to('blogPosts');
match('/posts/:blog_post_id').to('showBlogPost');
});