Im using anylogic in order to build a model of randomly moving cars.
In that model i want to gather some information on the agents (Cars) using a varivable and an event block.
On the model i want the event to set the variable carsLane with the lane of the car that is currently on the road and to do so every 2 seconds.
The thing is that every time the event is suppose to take place i get "NullpointerException" error and it happen so on every method of Car that im trying to use using the Event.
The event is on the Main tab and the code im using on the action box:
carsLane=Car.getLaneIndex();
On the image you can see the formation of the blocks and the code on the event's action box
Am i using the event wrong or is it something else?
Thank you for any kind of help.
This will be confusing to you, but the Agent Car that you defined in the model is NOT or does not contain the agents that are created in the carSource module, so doing carLane=Car.anything will give you an error, since the Car agent is probably empty or is not in any Lane.
To solve this, you need to do a bunch of things (and I will assume that you generate cars in your carsource in a way that there will be a maximum of 1 car in the road... if there are more, you have to do something different.
First: create a new Car agent with a population of cars, let's call it thecar (use the agent from the agent palette... not the "car type") with an initial population of 0.
This agent will be an extension of the Car type you created:
Second: In the car source, add your cars to a custom population:
And also, your car source will generate cars of the type thecar:
third: In your event now you can do:
carsLane=thecars.get(0).getLaneIndex();
And I created the model for you... find it here:
https://ufile.io/5jkqu
Related
I am trying to push a event towards GA3, mimicking an event done by a browser towards GA. From this Event I want to fill Custom Dimensions(visibile in the user explorer and relate them to a GA ID which has visited the website earlier). Could this be done without influencing website data too much? I want to enrich someone's data from an external source.
So far I cant seem to find the minimum fields which has to be in the event call for this to work. Ive got these so far:
v=1&
_v=j96d&
a=1620641575&
t=event&
_s=1&
sd=24-bit&
sr=2560x1440&
vp=510x1287&
je=0&_u=QACAAEAB~&
jid=&
gjid=&
_u=QACAAEAB~&
cid=GAID&
tid=UA-x&
_gid=GAID&
gtm=gtm&
z=355736517&
uip=1.2.3.4&
ea=x&
el=x&
ec=x&
ni=1&
cd1=GAID&
cd2=Companyx&
dl=https%3A%2F%2Fexample.nl%2F&
ul=nl-nl&
de=UTF-8&
dt=example&
cd3=CEO
So far the Custom dimension fields dont get overwritten with new values. Who knows which is missing or can share a list of neccesary fields and example values?
Ok, a few things:
CD value will be overwritten only if in GA this CD's scope is set to the user-level. Make sure it is.
You need to know the client id of the user. You can confirm that you're having the right CID by using the user explorer in GA interface unless you track it in a CD. It allows filtering by client id.
You want to make this hit non-interactional, otherwise you're inflating the session number since G will generate sessions for normal hits. non-interactional hit would have ni=1 among the params.
Wait. Scope calculations don't happen immediately in real-time. They happen later on. Give it two days and then check the results and re-conduct your experiment.
Use a throwaway/test/lower GA property to experiment. You don't want to affect the production data while not knowing exactly what you do.
There. A good use case for such an activity would be something like updating a life time value of existing users and wanting to enrich the data with it without waiting for all of them to come in. That's useful for targeting, attribution and more.
Thank you.
This is the case. all CD's are user Scoped.
This is the case, we are collecting them.
ni=1 is within the parameters of each event call.
There are so many parameters, which parameters are neccesary?
we are using a test property for this.
We also got he Bot filtering checked out:
Bot filtering
It's hard to test when the User Explorer has a delay of 2 days and we are still not sure which parameters to use and which not. Who could help on the parameter part? My only goal is to update de CD's on the person. Who knows which parameters need to be part of the event call?
I'd like to measure the time from order placement (agent Order) to delivery to the shop.
There are some delays inbetween due to assembly of the goods. But after that I need to transport it to a defined port by trucks and vice versa in the country of destination.
I figuered I have to use sources (creates my good agents) and sinks (arrival of my good at destination) for timemeasuring. So I can use TimeMeasureStart and TimeMeasureEnd but I am having trouble with how I acutally implement this in my flowchart in AnyLogic.
Any thoughts?
Thanks in advance!
Benj
Create three parameters in your order agent: timeEnter, timeLeave, timeInSystem. When the order is created, set agent.timeEnter=time() and whenever you dispose of them, type
agent.timeLeave=time();
agent.timeInSystem=agent.timeLeave-agent.timeEnter;
You can add this value into a dataSet, for example.
You can use the time measure start and time measure end blocks.
You simply place the 'start' block where you want to start measuring and the 'end' block where you want to stop measuring and then refer to the associated start block inside the end block
The screenshot is from the how to model that can be found in the AnyLogic How to examples in the Software
Or check the link here https://anylogic.help/library-reference-guides/process-modeling-library/time-in-system.html#measuring-time-in-system
This model runs by injecting products via a button that get sent to rooms USP1 and USP2. There is a fleet of transporters that carry the product to the next room by moveByTransporters as well as the logic that moves the product through the equipment by delays and seize/releases. The logic for USP1 and USP2 both move the product to the same Harvest room after their logic is complete.
The model randomly chooses which USP room to go to and when it goes through the USP2 logic there are no errors. By injecting a second product both USP1 and USP2's logic have a product moving through and meet at this Harvest logic.
When I run the model it works until there are multiple products and the error occurs. Looking at the restricted limits for USP1 I see a -1 still inside the limit.
[
well, somewhere within the RestrictedArea, you are letting additional agents "slip in" without registering them into the RestrictedArea.
One candidate is the weird "split2" that folds splitted agents back into the subsequent elements. This creates new agents within your RestrictedArea without them registering properly.
You cannot create new agents within a RestrictedArea as it will not notice that, see the help
Giving I have a dialog tree for booking a rental car.
The bot have a main Intent called "orderIntent" and a second intent called "colorIntent".
In the "orderIntent" dialog the user will be asked to chose for a car category, date, and price (all of those have a separate slot in this intent).
I want that the at any given moment in the dialog the user will be able to call the "colorIntent" intent and set up a color as he desires and when this is finish, to return back to the same place in the tree dialog that he previously left.
For example, when the user will be asked to pick a date for the booking, and will reply with "I want to chose a green color for the car" this will invoke the "colorIntent" intent and the user will be able to chose a color.
Afterwards the user should return to the same part of the dialog that he partially fulfilled and will be asked again to pick the date of the booking. I want to achieve that while maintaining the information he already partially fulfilled in the main dialog about the car catagory and price he already picked and the new information about the color he picked from the "colorIntent" intent.
How can I configure such logic in the AWS Lambda of the bot ?
https://github.com/awslabs/serverless-application-model/blob/master/examples/apps/lex-book-trip-python/lambda_function.py
Try seeing book_car function this will solve your problem. Because here they are taking some slot values of book_hotel and setting up in book_car.
Make use of sessionAttributes to achieve this because sessionAttributes remain across intents, while slots are only held within each intent.
Intent_A logic can run, filling slots as it goes, and the slot values should also be saved in sessionAttributes. Then at any point of IntentA, a user could trigger Intent_B.
Now Intent_A's slots are overwritten by Intent_B's slots but Intent_A's slot values are still saved in sessionAttributes.
Extra Information on how to change between intents:
You then have 2 choices:
(1) force the user to trigger IntentA again
with a prompt like, "To continue booking the car, please say, book a
car".
(2) use confirmIntent back to IntentA, but it will need to
ask a confirmation question like, "Would you like to continue booking
a car?" The response to that will go to Intent_A regardless, so
inside of Intent_A you need to just check the confirmationStatus
which will be either "Confirmed" or "Denied", based on how the
user responded to that question. If confirmed, then you can continue
Intent_A, and if denied, then you should close Intent_A.
(look into confirmIntent here under types of dialogAction)
After getting back into Intent_A, you should then check if any slot data is inside of sessionAttributes, and force this data back into the appropriate slots. Then your original logic can detect which slots are already filled, and continue where it left off.
During development of my application, I found that I need to emit some events that actually don't modify the state of the aggregate, but they are needed in order to update read models (transient events?). e.g. if in my code (domain model) I hold state of hierarchy of numbers in layers like:
1 4 7
5 8
3 9
and the read model is doing projection of events like (top number from left to right):
1
5
3
then, when I trigger event in aggregate root RemovedNumber(1), and if this is the only event I trigger (since it is enough to update aggregate state), read model will not know that it needs to replace number 1 with 4.
? <--- SHOULD BE 4 SINCE 4 IS UNDER 1
5
3
So here basically, I need to trigger additionally: NowShowNumber(4 instead of 1), and then read model will know to project:
4
5
3
Event RemovedNumber(1) should be kept in event store, since it affects internal state of aggregate. Event NowShowNumber(4 instead of 1) should also be stored in event store since it is affecting read model (and should be replayed on re-projecting it), but it should probably not be used during reconstruction of aggregate root from event stream.
Is this standard practice in CQRS/Event Sourcing systems? Is there some alternative solution?
Why doesn't the Read model know to show number 4?
Didn't the Aggregate emit an AddNumber(4) prior to AddNumber(1)?
Then the Read model has the necessary state replicated on his part, basically a stack with numbers, in order to pull the previous number and to show it.
In CQRS, in order to help the Read models, when a state changes and an Event is emitted, the Aggregate include bits of the previous state in the Event also.
In your case, the emitted Event could have the following signature RemovedNumber( theRemovedNumber, theNewCurrentNumber), and in particular RemovedNumber(1, 4).
I call these events out of band events and save them to a different stream than I hydrate aggregates with.
Haven't heard anyone else doing it but haven't heard any good arguments to not do it - especially if you have a legitimate case for posting events that have no effect at all on the aggregate.
In your case if I understand your problem well enough I would just have the domain write a TopLevelNumberChanged event which the read model would see and process.
And obviously it would not read that event when hydrating.
I cannot see that it is at all an issue having events that don't effect changes in your projections. Depending on the projection it may be that the projection ignores many events.
That being said, if you are saying that these two events go hand-in-hand you may need to have another look at the design / intention. How do you know to call the second command? Would a single command not perhaps do the trick? The event could return the full change:
NumberReplacedEvent ReplaceNumber(1, 4);
The event would contain all the state:
public class NumberReplacedEvent
{
int ReplacedNumber { get; set; }
int WithNumber { get; set;
}
From my understanding, there's no single correct answers. CQRS / Event Sourcing is just a tool for helping you to model your data flow. But it's still your data, your business rules, your use case. In other words: Some other company could use the exact same data model, but have a different event structure, because it fits better for their use case.
Some example:
Let's imagine we have an online shop. And every time a customer buys a product, we decrease the inStock value for that product. If the customer sends the product back, we increase the value.
The command is pretty simple: BuyProduct(id: "123", amount: 4)
For the resulting event we have (at least) 2 options:
ProductBuyed(id: "123", amount: 4) (delta value)
ProductBuyed(id: "123", newInStockValue: 996) (new total value)
(you could also publish 4 times a simple ProductBuyed(id: "123") event)
Or you can have multiple resulting events at the same time:
ProductBuyed(id: "123", amount: 4)
InStockValueForProductChanged(id: "123", newValue: 996)
An online shop will possibly have multiple read models that are interested in these events. The Product Page wants to display only 996 items left!. And the Shop Statistics Page wants to display sold 4 items today. Though both options (total and delta) can be useful.
But also both Pages could work if there's only one of both events. Then the read side must do the calculation: oldTotal - newTotal = delta or oldTotal - delta = newTotal.
There are even more possible solutions. For example:
Checkout Service publishes ProductBuyed(id: "123", amount: 4) event
Stock Service receives this event, decreases the stock and then publishes the InStockValueForProductChanged(id: "123", newValue: 996) event
It really depends on the needs of your business.
My suggestions:
I prefer when the write model is only responsible for managing the business rules. Get Command, validate it, publish event(s) which look pretty similar to the command contents.
And the read model should be as simple as possible, too. Get Event, update model.
If calculations have to be done, there are a few options:
The calculation is part of a business rule? Then your write side has to compute the result anyway. In this case you already have written the algorithm, the CPU has done its work, and you have the resulting value for free. (Just include the result with the published event)
The calculation is really complex and/or there are multiple event consumers that need the result. Then it might be better to compute it once and include the result in an event, instead of computing it n times for every involved event consumer. Complex could mean:
Takes a lot of time
Very CPU / memory intensive
Needs special / huge external libs (imagine you had to include some Image Processing library with every read service)
The calculation is the result of a combination of a lot of different events (i.e. it's getting complex): Build an external service, which is responsible for the calculation. This way you can easily scale out by providing multiple instances of this service.
If the calculation is not part of a business rule and it's simple and only a single service needs the result or if it's only relevant for the read model: Place it in the read side.
In the end it's a tradeoff:
Duplicate algorithms? You could have multiple event consumers written with different programming languages. Do you want to implement the algorithm multiple times?
More network traffic / bigger event store? If you include the calculation result with the event, there's more data to store and transfer between the services. Can your infrastructure handle that?
Can your write / read service take the additional load?