Simulation Framework: How to make a Lambda: A lambda class should extend ALambda or some subclass of ALambda. The namespace of the class must be ModuleWorker.Lambda. The lambda class needs to define its input and output port names as well as implement the BeginExecution, Initialize, runModule, and StopExecution methods o In the constructor of the class, the inputs and outputs lists need to be filled with the names of the input and output ports. Then InitInputsOutputs() needs to be called. (This needs to all be moved to a constructor of ALambda). The names of the input and output port need to match the names given to the SimulationInstance. o The Initialize method should not do anything for a normal lambda class since all of its inputs come via the input ports defined in the constructor. o The BeginExecution method is called before the simulation starts. In this method, the lambda should output a starting value to each of its output ports defined in the constructor. o The runModule method is called every time the lambda receives a tick signal. In this method, the lambda should do its necessary calculations and store the outputs in the outputValues dictionary of ALambda. To read input values, use the inputValues dictionary of ALambda. Both inputValues and outputValues are keyed by the name of the port the value is associated with (defined in the constructor), and the values are just the object being inputted/outputed, not a DataPacket object. o StopExecution method is called when the simulation is stopped by the user. Currently no lambdas except the DriverLambda do anything in StopExecution. Missing functionality: Currently, ports and connections are not typed. There needs to be typing on them in order to avoid the type casting in lambdas. In order to accomplish this, a mixed-type dictionary needs to be used to hold the different types of InputDelegates and OutputDelegates in ALambda. An IPort already has a Type field, but is not being used. Currently, stopping a simulation doesn't work correctly. The driver doesn't stop ticking even after its StopExecution method is called. Also, it needs to be tested whether the memory used by all the modules and lambdas is freed when all the drivers are stopped. Currently, the timestep values outputted by DriverLambdas do not take into account the timestep values outputted by the DriverLambda from the next-outermost composite. So modules only know the time relative to their composite module, not the global time. Outputting results from the OutputLambda all the way back to the gui has not been tested. Hacks/Bugs that need to be fixed ALambda o There are functions (dval, fuelVal, pollInfo, etc.) that do not belong in this class. They should be moved to a subclass of ALambda. o The Initialize method is only used by internal lambdas like composite, driver, and done. But since this is an abstract method, it needs to be implemented in all lambda classes. There should be a subclass of ALambda that provides a no-op behavior for Initialize that all user-defined concrete lambdas can inherit. o The internal lambdas override the run method and don’t implement the runModule method. This is opposite of user-defined lambdas. This needs to be changed so that implementations of internal and user-defined lambdas are more consistent. In SimulationInstanceImpl, there are a lot of hardcoded strings for the port names of nonuser-defined lambdas (like composite lambda, done, takeoff, output...). These strings should be made fields of some constants class so that they can be easily modified later if necessary. In WorkInterfaceImpl, the WorkerHandler is hardcoded in the constructor. Instead, the WorkerHandler endpoints need to be read from Azure Tables or some other storage. File descriptions: ModuleWorker project - Shell folder o ModuleShell.cs - This is the generic shell that encloses a lambda. It is responsible for dynamically creating ports through which lambdas can receive their inputs and send their outputs. Attribute folder o InputAttribute.cs - represents an attribute that should tag a dictionary that holds all inputs for a lambda. Used for reflection so the ports can be created dynamically in the ModuleShell o OutputAttribute.cs - represents and attribute that should tag a dictionary that holds all otuputs for a lambda. Lambda folder o ILambda.cs - Interface that defines a lambda o ALambda.cs - The abstract represenation of a lambda. Contains the dictionaries that define the input and output ports for a lambda, as well as methods for initializing and running a lambda o AssumptionLambda.cs - a lambda that outputs assumption values every timestep. The module with this lambda is connected only to the outermost composite module of the simulation o CompositeLambda.cs - the lambda that handles the routing of inputs and outputs from the modules it contains. Also causes its Driver module to tick every timestep. o DoneLambda.cs - the lambda that reads the outputs of all the modules in a composite module and decides if the outputs are ready to be sent out of the composite. It causes the Driver module to stop ticking. o DriverLambda.cs - lambda for the Driver module. Every tick, it asks the Takeoff Module to route the inputs of the composite to the correct inner modules, sends a tick signal to all the inner mdoules, and then asks the Done module to check if it should stop ticking. o OutputLambda.cs - lambda that outputs the results of the simulation back to the Framework. A module with this lambda is only connected to the output port of the outermost composite. o TakeoffLambda.cs - lambda that reads the inputs of its composite module and routes these inputs to the correct inner modules of the composite. ModuleHost.cs - This is the class that keeps track of what modules are on a specific virtual machine. It accepts connection requests to the modules it hosts and starts and stops modules as well. WorkerHandler.cs - This class manages a single ModuleHost. It receives configuration objects for modules and connections and uses them to create ModuleShells and Lambdas and their connections. WorkInterfaceImpl.cs - This is the interface between the SimulationInstance and the WorkerHandler. It utilizes the SimulationNetworkLayer to distribute modules across multiple ModuleHosts and establish communications between ModuleHosts DataPacket.cs - This is the object that is passed between lambdas. It encloses the timestamp associated with its data. SimpleDataConnection.cs - Represents a connection between ports on ModuleShells. It can write data to all the ports that are part of this connection SimpleDataPort.cs - Represents a port on a ModuleShell. This port will queue up data packets it receives and return the next data packet in its queue when needed. This port is used for all normal inputs and outputs for lambdas. NonQueuingPort.cs - Another type of port which does not queue up data packets it receives, but rather immediately calls a Callback delegate function when it accepts data. This type of port is used only for the TimerPort and BeginExecutionPort on ModuleShells. TimerPort.cs - the port that has a callback delegate that is called for every tick by the Driver modules BeginExecutionPort.cs - the port that has a callback delegate that is called in the begin execution phase of the simulation SimulationInstance project SimulationInstanceImpl.cs - represents an single simulation. It is responsible for initializing all the configuration objects for modules and connections that are sent to the WorkerHandlers. Also has methods that can start and stop a simulation.