control moto's state transitions of EC2 instances? - moto

To test that my application handles state transitions correctly, I'd like control over the lifecycle of moto's fake EC2 instances:
Rather than have instances start immediately in running, it would be nice to have them start in pending, let me confirm some things, and then explicitly transition them to running.
Relatedly, there are some actions I'd like to trigger in my tests when the instances switch to running.
Is any of this possible? I found InstanceBackend in moto's code -- is there a way for users to hook into or override methods there?

There are a few feature requests for more control over the transition cycle, but nothing has been implemented yet.
It is possible to use the internal API to set the status directly, as you said, using the InstanceBackend.
If you only have one instance, you can use the following code:
ec2_backend = moto.ec2.models.ec2_backends[my-region]
list(ec2_backend.reservations.values())[0].instances[0].state = "..."
If you have multiple reservations, you can use the reservation ID like this:
ec2_backend.reservations["r-7df1884b"].instances[0].state = "..."
Note that both AWS and Moto use two properties to track state, state and state_code. Only updating state may result in undefined behaviour, so you may want to update both to ensure they are in sync:
ec2_backend.reservations["r-7df1884b"].instances[0].state_code = ..
Note that this is an internal API, so changes to this data structure may occur without warning.

Related

How to queue requests in React Native without Redux?

Let's say I have a notes app. I want to enable the user to make changes while he is offline, save the changes optimistically in a Mobx store, and add a request to save the changes (on the server) to a queue.
Then when the internet connection is re-established I want to run the requests in the queue one by one so the data in the app syncs with data on the server.
Any suggestions would help.
I tried using react-native-job-queue but it doesn't seem to work.
I also considered react-native-queue but the library seems to be abandoned.
You could create a separate store (or an array in AsyncStorage) for pending operations, and add the operations to an array there when the network is disconnected. Tell your existing stores to look there for data, so you can render it optimistically. Then, when you detect a connection, run the updates in array order, and clear the array when done.
You could also use your existing stores, and add something like pending: true to values that haven't posted to your backend. However, you'll have less control over the order of operations, which sounds like it is important.
As it turns out I was in the wrong. The react-native-job-queue library does work, I just made a mistake by trying to pass a function reference (API call) to the Worker instead of just passing an object that contains the request URL and method and then just implement the Worker to make the API call based on those parameters.

opendaylight: how to deploy different applications on different switches?

I am using Oendaylight (carbon) to develop an SDN application consisting of multiple switches that connect to a controller. I want to be able to deploy different applications on different switches when they connect. How can I specify this? For example when openflow:1 connects, I want to deploy an L2 switch on it and when openflow:2 connects, I want to deploy a different application on it. Thanks.
First of all, you do not deploy applications on switches. Applications run on controller, you can add a logic which programs selected switches only.
What you essentially want to do is reactive programming; wait for events and act accordingly. This can be easily achieved by hooking the event listeners to the nodes in YANG model of the application. Any change in these nodes will be then notified to your application which can then do selective network programming.
In the example mentioned, you will need to use "InstanceIdentifier" object to identify which data model's events you are interested in listening.
InstanceIdentifier<Node> nodeID = InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(node.getId())) .augmentation(FlowCapableNode.class)
.build();
Now simply register a listener to this IID by using DataBroker object's registerDataChangeListener method.
db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, nodeID, this, AsyncDataBroker.DataChangeScope.SUBTREE);
At this point in time, you will be notified of any update (addition/modifification/deletion) of the switches you have registered for.
Finally to catch the event use/override DataChangeListener interface's onDataChanged method and add your fancy logic.
The similar logic can be fine grained to listen to activities on particular flow tables, flow rules, etc on the switch.

Integration AutobahnJS with Vue.js

I'm looking for an easy way to integrate Vue.js with AutobahnJS.
I've already checked this repo for guidance/template, but my main problem is that Autobahn has two layers of "wait":
First you create a Connection/Session instance
You wait for it to connect (maybe even retry N times)
Only after this can you access the session methods (subscribe/call/etc..)
With my limited JS knowledge (i'm a backend dev), i have two ideas:
Create a global variable which will be assigned to the autobahn session after connection. This will surely cause cases where the var is not yet set, so I'd have to check it's existence every time I want to subscribe from a vue instance.
Place the Vue init code into the Session connected callback, but then that would delay the whole application, which is obviously bad too.
I'm looking for a simple and efficient solution, not necessarily a full-fledged plugin (which I haven't found anywhere).
Any help/advice is appreciated!
I've been looking for a plugin like this: https://github.com/lajosbencz/vue-wamp
Plugin calls are deferred until autobahn Session is ready, unsubscribe and unregister are automatically called component-wise.

Circular module dependencies between stores

In my react native app that tracks instrument practice I have three stores:
SessionStore
GoalStore
InstrumentStore
The stores each manage one model (Session, Goal, Instrument) and getting/updating the server via a REST api.
The SessionStore listens to actions regarding Sessions (obviously): session.add, session.update. But it also listens to changes to the other stores, to be able to update the Sessions if a Goal or Instrument changes name.
Correspondingly the InstrumentStore listens to Instrument actions, but also to Session actions to update statistics on how many sessions uses a particular instrument.
To be able to not have race conditions, the InstrumentStore will act on the action session.add but wait for the SessionStore to handle the action first (to ensure the Session has been updated in the API). To do this I use dispatcher.waitFor with the SessionStore dispatchToken as a semaphore.
The problem: since all stores use each others dispatchTokens they all have to import each other. This is a circular dependency on modules and leads to strange race conditions. Sometimes one of the stores haven't been constructed when it's included by one of the other stores.
Here are my stores: https://github.com/osirisguitar/GuitarJournalApp/tree/feature/flat-ui/js/stores
Am I using the flux pattern the wrong way?
Addition
This is what I want to happen (in sequence):
Session is updated:
Send updated session to API
Refresh SessionStore
Refresh GoalStore
Refresh InstrumentStore
2, 3 and 4 need to wait for 1 to complete, that's why GoalStore and InstrumentStore need the SessionStore dispatch token.
Goal is update:
Send updated goal to API
Refresh GoalStore
Refresh SessionStore
2 and 3 need to wait for 1, this is why SessionStore needs the GoalStore dispatchToken which introduces the circular dependency.
You have some duplication going on.
All stores will hear all dispatches. That's the beauty of having a single dispatcher. So when you dispatch a sessions.add or sessions.update action, you're hitting three different Stores, and two of them are doing the exact same thing. That's a no-no.
As a rule, each Store's dispatch token should only be responsible for updating that store. So your Goal and Instrument stores should not be updating the SessionsStore. The .refresh and .emit should be happening within the SessionsStore dispatch token only.
EDIT to answer your edited question.
I think your confusion is because you're not recognizing that the dispatcher.register takes in a function as it's argument, and not an object.
Functions, in JS, do not evaluate their contents on declaration. They are evaluated when executed only.
Simple example;
func = function(){ console.log(testVar) } // No error, even though testVar is undefined
func() // ERROR: testVar is undefined
var testVar = 'hey';
func() // log: 'hey';
dispatcher.register takes a function as it's input, and returns an key (in the format ID_#). That key is generated by the dispatcher itself without running the input function. The input function is simply stored for later and run each time a payload is dispatched.
That means that you don't need the internal variables to be defined until your first dispatch. And because you also don't want to dispatch anything until you've created your stores, this becomes a non-issue.
But it also means that the dispatcher, by default, has a sort-of circular dependency against itself (relying on the return values of it's own functions, as stored in external variables). But that's the design of the dispatcher. Unless you're going to write a new dispatcher, that's just part of the deal.
It's also worth pointing out that if you create a true circular dependency by calling multiple waitFors that deadlock against one another, the dispatcher will correctly throw an error saying as much;
Dispatcher.waitFor(...): Circular dependency detected while waiting for ID_#

Apache ignite listening to state change of objects in local nodes

I am investigating a use case where ignite has to listen to changes of a property of an object in the data grid and do some operations on that object. For performance, I want the processing to be done on the same node where the data is.
How can I get an event when the property of a object has changed to a specific value (eg. Object 'X' has a property 'state' which is set to 'scheduled' from 'created') and make sure that only events are taken from the node where the object lives in?
How can I make sure that when I got the event and start processing it, nobody else changes the object (only read is allowed) until processing is finished (in other words, a transaction starts as soon as the event is picked up)?
How can I make sure that the processing code is deployed to all nodes (processing is stateless) and that it only operates on local data (without having a hard link between data object and code, in other words, if the processing code is updated in the future, the objects stay untouched)
What I got from the docs is the following:
// Local listener that listenes to local events.
IgnitePredicate<CacheEvent> locLsnr = evt -> {
// CODE
return result;
};
// Subscribe to specified cache events occuring on local node.
ignite.events().localListen(locLsnr,
EventType.EVT_CACHE_OBJECT_PUT);
In the CODE block; I have to check for a state change on 'evt.newValue()', can't that be done earlier? Ie. as a paremeter to localListen somehow?
In the CODE block, is the Object locked until I return the result? In other words, is it in here that I am sure nobody can changes the object and that I can safely change my Object? IMO it is a strange place to do that in a 'Predicate' definition and not in a handler class.
Sven
Sven,
Your code looks correct and should work as you expect. Answering your questions:
Event listener is called right after the value is updated, so I think it's OK to check the field you're interested in inside the listener. If the field is not changed, just return right away.
The object is locked, because listener is called inside the sync block for the entry. You can modify the same object, but I would not recommend to execute any sync operations like cache updates inside the listener because it's error-prone and can affect performance. You should do this asynchronously, so that the lock is released as soon as possible.