Akka.net routee's parent - akka.net

It maybe a newb's question, but I can't find an answer both here and on http://getakka.net/docs/.
So, the question is - who is a Parent for a routee actor? The actual router's supervisor or a router itself?

Well, after some additional search, I guess I found the answer here - http://getakka.net/docs/working-with-actors/Routers#pools-vs-groups
Routers are implemented as actors, so a router is supervised by it's parent, and they may supervise children.
Group routers use routees created somewhere else, it doesn't have children of its own. If a routee dies, a group router will have no knowledge of it.
Pool routers on the other hand create their own children. The router is therefore also the routee's supervisor.
In my case, it was a pool router, so a router will be an actual Parent of the routee.

Related

How to initialize a component from another micro frontend that lazy loaded

I'm working on a micro frontend application.
The MFEs are lazy-loaded when needed. Each MFE exposes components. In order to minimize the coupling between the MFEs, it is suggested to avoid passing props and callbacks between the MFEs and rely on indirect communication like Pub/Sub pattern (we would like to be framework agnostic). I saw there are a few libraries that provide to subscribe for events / specific topics and publish events and some of them also support retrieving the latest event.
So it will be something like this:
MFE A need to initialize a component B.X from MFE B with some initialization data
MFE A publishes event - topic: "B.X init" data:{...}
MFE A render component B.X
MFE B is loaded and initialized (in case it has not loaded yet)
MFE B subscribe to the event with the topic "B.X init"
MFE B initialize component X with the received data
My questions are:
Is there a better way of doing it?
In the case of 2 instances of the same component, how to initialize each one of them with different data? another info about that?
Thanks
I will try to answer the "big" parts and leave details/implementation to you as this question has many implied questions within it.
I would say it seems wrong for 1 MFE to access another MFE component (Also how are you exposing this inner component?)
It seems that when developing you have to run another MFE (or at some stage maybe all of them) in order to have a single component available to another MFE - you should strive to keep them non coupled as you wrote yourself.
I suggest to share some common components combined with an events system.
This is a pic (from the link at the bottom) that illustrates sharing of common components(or other stuff like util library).
I will show the basic approach:
Make a shared library exposing shared components
{
"name": "#shared/ui",
"type": "module",
... rest of values
}
Import in each MFE using it
//package.json
"dependencies": {
"#shared/ui": "*"
}
//MFE
import { MyButton } from '#shared/ui';
function App1() {
return (
<div>
<div>App 1</div>
<MyButton/>
</div>
)
}
This is a static import - according to your needs you can add an event listener that changes the state of the MFE and causes a re-render (you can find many examples on SO) with the value received in the published event.
Check my answer here for basic events communication - this is a basic pub/sub system that should satisfy your requirements.
So to summarize:
Share common components
Communicate using events
In MFE:
Import shared components
Listen/subscribe to the relevant events - init(and render) the shared components using your logic
Extra:
If you have a shell app the "holds" the structure and acts as an entry point you can add this shared library to the shared part of Webpack5 & Module Federation (in the shell app).
Hope this helps - it's basic but if you get the idea you can advance in your direction from here. Questions/comments welcome.
BTW - this heavy read by Oreilly is just amazingly good! Check the part under headline "Module Federation" for code sharing.

Multiple Vue apps, multiple entry files, same Vuex/Vue3CompostitionApi store [lost reactivity]

I am trying to iteratively replace .cshtml razor views with what I wanted to call Vue "mini-apps". Which should be somewhere in between a micro-frontend and a classic SPA. The aim is to share some of the code base, mainly dependencies. Compile a common chunk-vendors.js and have the "mini-apps" as separate javascript entry files to place on appropriate views. As performance demand would grow, I would progress into splitting chunk-vendors.js and optimize via lazy-loading.
The problem I am hitting here is trying to make two root Vue instances talk to each other through a shared state. Right now only the app that is imported/mounted first stays reactive. I thought that my problem was in the Vue 2 reactivity system/how Vuex binds itself to a concrete Vue instance here. When I implemented a primitive store, the situation ended up being exactly the same.
What confuses me about this is that if I were to instantiate two applications in a single main.js entry file, the store sharing would just work. Which suggest that Vue is either creating some kind of hidden root instance or that my Vuex code analysis deduction of it binding to a concrete instance was incorrect.
I would highly appreciate it if someone could tell me why this can't work, optionally suggest a workaround?
I have created a reproduction both in Vue 2 with Vuex and in Vue 3 with composition API/primitiveStoreImplementation here.
Vue-cli is building the app in an MPA mode with pages specified in vue.config.json, then imported in the root index.html file. The store is initialised once and saved for later check/loading on the window object. In the context of asp/razor I would have webpack set up to remove the redundant files, only leaving javascript bundles. Also, the dev proxy would proxy everything except the path to the script bundles. All of this is removed for the sake of the demonstration.
(once I find a solution I hope to replace the source link with specific code snippets)
Options considered:
I am trying to avoid it, but I might have to always run a "coordinator" root instance that will check the presence of certain elements on a page and load/unload the "mini-apps" as components using something like portal-vue when needed. That coordinator would also contain a state with modules, some of which would be marked as "shared" thus operations from multiple "mini-apps" would be allowed (ownership flag check).
I have considered sessionStorage/localStorage, the problem is that the 'storage' events are only triggered across tabs and not within one document first |Note. I would have to trigger a custom event or play around with iframes. Feels too hacky, but that might be an axiom here. It would also duplicate the same state across many store instances.
These are some relevant articles I have found on this topic:
Probably closest to what I am trying to achieve:
Using Vuex with multiple Vue instances
Same but different:
Build Vue microfrontend app (with routing and vuex store)
The use case for multiple entries are sub-apps that don't coexist on the same page, although they can. They could be web components or regular app bundles. They can even interact with each other but they need something else for this - global event bus or a mediator app that passes data between them.
The problem is that there are more than one Vue library copies and/or more than one Vuex store instance. In order to avoid this, they would need to be precisely loaded only once on the page and reused between apps, i.e. vue and vuex are loaded as CDN libs, possibly used as Webpack externals to use window.Vue and window.Vuex transparently for respective import. Not only Vuex but store needs to be a singleton on the page (basically a said mediator). This is acceptable solution but primarily suitable for existing applications that have design restrictions and need a workaround.
I am trying to avoid it, but I might have to always run a "coordinator" root instance that will check the presence of certain elements on a page and load/unload the "mini-apps" as components using something like portal-vue when needed.
This is the common way to do this. Vue 3 has teleports that has give less control than portal-vue. It has no downsides for application design if done properly. The same thing is achieved similarly in other frameworks (Angular, React) as well, where portals appeared earlier.
I have considered sessionStorage/localStorage, the problem is that the 'storage' events are only triggered across tabs and not within one document
This is solved by using window postMessage and message event in the same tab. In case this shouldn't be limited to a single window, there are third party libs that use both for cross-tab synchronzation, a native alternative is BroadcastChannel that has less browser support than LS but doesn't have its limitations regarding tabs.

Vue page cannot open after refreshing the page

I added the routes dynamically to the router and I can visit all pages with router-view. However, when I try to refresh the page I cannot visit the page again although the URL is the same. It is http://localhost:8081/me.
this.$router.addRoute("Main", {
path: '/me',
name: 'Me',
component: () => import(`#/components/Me.vue`)
});
As I said, I can normally visit the page "Me", but when I refresh it, I cannot see its content anymore with the warning:
[Vue Router warn]: No match found for location with path "/me"
I tried to create router with createWebHistory("/") after reading the cause of the error but nothing seems to change. I will appreciate any help.
There are two reasons why this would happen.
First serving SPA application from the server.
Make sure that your back-end is set to serve index.html file for all routes since back-end server is unaware of the routes set by client-side router. Something like express-history-api-fallback-middleware can help is using Node.js/Express.js.
Second problem is that of using addRoute.
As you described, the problem could be that Vue router is taking routing decision before your code in components/common/LeftMenu.vue is getting executed which is responsible for calling addRoute(). Ensure that this code is called before routing decision is being made. Best way would be to move this logic in top-level application component. And, if you can move that to top-level components, that means you can try to declare all routes while defining the router.
Why that should be done?
Using addRoute is not necessarily an anti-pattern but having to rely on addRoute is often code smell. You would really need it in extremely rare scenarios. Routing is a high-level architectural concern for your application and thus better to be declared upfront somewhere at top-level module even before application is getting initialized. Low level components should not attempt to manipulate routing data structure (violation of DIP principles).
One scenario where you might be tempted to use addRoute is taking decision after some data manipulation by the component with addition of some API call. That seems legitimate need but then to address that there are better ways. Considering using route guards (guards support async resolution too!) and prevent user from entering the view till the guard is resolved successfully.

Vue instance per component over single instance

due to the structure of our websites we currently are unable to create one main app instance, as there is too much HTML within this.
So instead we are currently looking for the class of app and then creating a new Vue instance per component, which isn't great for communicating between components but it's our current work around.
We are working to create a new structure to support just one overall app. However, just wondering if creating a new instance of Vue for each component is bad for browser performance over having just one instance with the component inside this?
Short answer: No
There won’t be any performance difference between an app that uses a root Vue component with child components and an app that uses multiple root Vue components.
All components are still just Vue instances - so it isn’t any different. The only difference is the organization and usage of the instances.

Floodlight controller routing algorithme

I recently started working with SDN and floodlight controller. I want to changing routing algorithme in floodlight by deleting the algorithm exist (Dijkstra algorithm), any link for that ?
Floodlight controller has a topology manager that takes care of maintaining the
network graph, functionalities for finding routes through the topology via algorithm for the controller. Dijakstra runs in topology manager. You may need to update the Topology manager and its related dependencies as per your requirement.
The below link could be one good starting point
https://github.com/floodlight/floodlight/blob/master/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
Based on Dijskstra, the Yen's algorithm shall form shortest path, in the order of shortest path which shall get stored in pathCache for usage. The Topology manager interacts and helps in exposing the path information.
Application modules like Forwarding module shall retrieve the path from Topology Manager and then insert flows over the path based on learned source, destination.
Controller module like TopologyService help in maintaining the topology related information for the controller, as well as to find routing in the network.
You may need to update the modules as per your algorithm with few additional details https://floodlight.atlassian.net/wiki/spaces/floodlightcontroller/pages/1343513/How+to+Write+a+Module