SYSTEMS AND METHODS FOR EXECUTING DYNAMIC CODE IN A SOFTWARE CONTAINER

A method for executing dynamic code in a container image is described. The method includes running a first instance of the container image; retrieving first computer code from a first defined location and executing the retrieved computer code in the first instance; running a second instance of the container image; retrieving second computer code from a second defined location and executing the retrieved second computer code on the second instance. A corresponding system and non-transitory computer-readable medium are also described.

FIELD

The field generally relates to software containers. More specifically, it relates to systems and methods for executing dynamic code in a software container.

BACKGROUND

A software container is a mechanism that allows for software to be virtually packaged and isolated for deployment. A container consists of a virtualized runtime environment that allows applications to be abstracted from the environment in which they actually run.

Software containers can be instantiated from a container image. A container image is a static file that includes an entire runtime environment, including a software application's executable code and any dependencies needed to run the application, such as any required libraries, tools, configuration files, etc.

By definition, a container image is immutable. Accordingly, if a software application in a container needs to be modified, a new container image must be created. As can be appreciated, in cases where a containerized software application needs to be modified often, this can result in having to store, maintain, and access many different container images. This can be time consuming and costs bandwidth and storage.

SUMMARY

According to an aspect, a method for executing dynamic code in a container image is provided. The method includes: running a first instance of the container image on a first host server; retrieving first computer code from a first defined location external to the container image; causing a code execution module in the first instance of the container image to execute the retrieved computer code; running a second instance of the container image on the first host server or on a second host server; retrieving second computer code from a second defined location external to the container image; and causing a code execution module in the second instance of the container image to execute the retrieved second computer code.

According to an aspect, a system for executing dynamic code is provided. The system incudes: memory storing a container image, a first instance of the container image running on a first host server, and a second instance of the container image running on the first host server or on a second host server. The container image includes: a code import module configured to retrieve computer code from a defined location external to the container image; and a code execution module configured to execute the retrieved computer code. The code import module of the first instance of the container image is configured to retrieve first computer code from a first defined location external to the first instance of the container image; and the code execution module of the first instance of the container image is configured to execute the first retrieved computer code. The code import module of the second instance of the container image is configured to retrieve second computer code from a second defined location external to the second instance of the container image; and the code execution module of the second instance of the container image is configured to execute the second retrieved computer code.

DETAILED DESCRIPTION

With reference toFIG. 1, a system100for containerized software development is shown according to an embodiment. Broadly described, the system100includes an image registry101, a container orchestrator105, code storage109, a plurality of data sources113, and output storage115. Each of these components can communicate with one another via a network117, such as a local area network (LAN), wide area network (WAN), the internet, and/or other networks or combinations thereof.

The image registry101is a service configured to host and distribute container images103. Once a container image103is created, it can be stored on the image registry101so that it can be subsequently accessed and used. In the present embodiment, the image registry101is a shared registry, allowing for container images103stored thereon to be shared among users, such as a team of developers. As an example, a first user can create a container image and store it on the registry101. The first user and/or one or more second users can subsequently pull a copy of the image from the registry101to run separate instances of the same container as defined by the image. In the present embodiment, the shared registry101is private in that only a group of authorized users (such as the team of developers) can have access thereto. Moreover, different permissions can be granted to different users, such that only some users can be authorized to write (i.e., push) to the registry101, while others can only be authorized to read (i.e., pull). It is appreciated that other configurations of registry101are possible. For example, in some embodiments, the registry101can be a public registry.

In the present embodiment, the registry101is configured as a repository in that it can store and keep track of a collection of related images, such as multiple versions of container image103. As an example, an initial version of a container image can be stored in the registry101(ex. v.1). If a user modifies the container defined by the initial image, they will need to subsequently create a new image to define the modified container. This new image can be pushed back to the registry101and, instead of overwriting the initial version of the container image, the new container image can be stored as a new version in the registry101(ex. v.2). This can continue for any other number of versions n of the container image. A user can subsequently pull the latest version of the container version103or choose to pull any previous version (ex. v.1, v.2, v.n). Although version numbers have been described for keeping track of related images, it is appreciated that other tagging schemes are possible.

The container orchestrator105is a system configured to substantially automate the deployment, management, scaling, and networking of containers. The container orchestrator105can, for example, be implemented via the Kubernetes platform, although it is appreciated that other platforms are also possible. In some implementations, the container orchestrator105can facilitate managing a plurality of host servers107comprising physical and/or virtual machines running one or more operating systems, such that container instances can be run thereon. The container orchestrator105can further communicate with image registry101to facilitate deployment of container images103on the host servers107. As an example, a user can issue a command to the container orchestrator105to run a new instance of a given container image. The container orchestrator105can then pull the appropriate container image from the image registry101, identify a suitable host server107, and then run an instance of the container image on the identified host server107using an appropriate container platform, such as Docker or any other suitable platform. Although not explicitly described herein, one skilled in the art will appreciate that the container orchestrator105can provide various other functionalities.

The code storage109comprises persistent storage allowing for user-created code111to be stored and subsequently accessed. As can be appreciated, the code storage109can be implemented via various mechanisms. For example, in some embodiments, the code storage109can comprise a code repository service, allowing for storing and maintaining different versions of code. In such embodiments, the code storage109can store code for a plurality of users and maintain a plurality of versions of each user's code. It is appreciated that the code storage109can comprise other storage mechanisms. For example, the code storage109can comprise one or more databases and/or one or more file systems. It is further appreciated that the code storage109can comprise different storage locations, such as network storage and/or storage that is local to a user workstation and/or to a host server107. Preferably, at least some of the code storage109is accessible to the container orchestrator105, to the host servers107, and/or to containers running on the host servers107.

As can be appreciated, various types of code111can be stored on code storage109. For example, the code111can comprise source files in one or more programming languages, including compiled languages (such as C++) and scripting languages (such as Python). The code111can further comprise compiled code, such as executable binaries and/or libraries. In the present embodiment, and as will be described in more detail hereinafter, the stored code111comprises dynamic code that can be imported into, and executed by, a running container.

In addition to code storage109, the system100can further include data sources113and output storage115. Data sources113can comprise one or more persistent storage locations and/or databases that provide data that can be used as an input to containerized applications. Such data sources113can be provided, for example, by one or more data vendors. Similarly, output storage115can comprise one or more persistent storage locations and/or databases that provide a location for storing output data of containerized applications. As an example, in embodiments where a containerized application is configured to predict commodity pricing based on weather data, the data sources113can comprise current and/or historical weather data and commodity pricing acquired from a data vendor, and the output storage115can store predicted outcomes and/or application logs. It is appreciated, however, that many other configurations are possible.

Although in the illustrated embodiment the code storage109, data sources113, and output storage115are illustrated as separate logical entities, it is appreciated that they can be at least partially implemented using a common storage service, such as Amazon S3 or another suitable service.

As can be appreciated, the above-described system100can allow users to develop, share, and test containerized applications for rapid deployment. In a first example, the system100can be used to develop a containerized artificial intelligence (AI) model. A first user can program a first iteration of an AI algorithm and store their source code on code storage109. The AI algorithm could, for example, analyze consumer data to identify consumers in need of financial assistance, such as payment deferments on loans. When the first user is satisfied with the first iteration of the AI algorithm, the AI model can be packaged in a container, saved as a container image, and pushed to the image registry101. Once stored on the image registry101, it can be deployed by the container orchestrator105for testing. If changes are required, the first user can create one or more subsequent iterations of the AI algorithm and repackage the AI model with the subsequent algorithm iterations for testing using containers. Meanwhile, second users can also work on their own iterations of the AI algorithm and deploy them for testing in a similar manner using containers. The iterative development process can continue by first and second users until the AI model behaves as desired and is ready for deployment in a production environment.

As a second example, the system100can be used to develop a containerized trading application. A first user can program a first iteration of a trading algorithm and store their source code on code storage109. The trading algorithm can, for example, include various logical operations defining when to buy and/or sell stocks based on different parameters. In some embodiments, such logical operations can utilize one or more trained AI models or business rules. When the first user is satisfied with the first iteration of the trading algorithm, the trading application can be packaged in a container, saved as a container image, and pushed to the image registry101. Once stored on the image registry101, it can be deployed by the container orchestrator105for testing. If changes are required, the first user can create one or more subsequent iterations of the trading algorithm and repackage the trading application with the subsequent algorithm iterations for testing using containers. Meanwhile, second users can also work on their own iterations of the trading algorithm and deploy them, for testing in a similar manner using containers. The iterative development process can continue by first and second users until the trading application behaves as desired and is ready for deployment in a production environment.

As discussed above, a container image is immutable by definition. Accordingly, under normal circumstances, each iteration of the trading algorithm would require generating a new, distinct container image containing the trading application with the new iteration of the algorithm. Generating a new image for each iteration of the trading algorithm can significantly slow down the development of the trading algorithm and can require managing a large volume of different container images. It is therefore preferred to have a container configuration and corresponding method that allows a single container to run different iterations of code without having to generate and deploy a new container image each time.

Accordingly, with additional reference toFIG. 2, a method for utilizing the system100to execute dynamic code in a container is shown according to an embodiment. As will be described in more detail hereinafter, dynamic code corresponds to code that is not a fixed as part of a container image (i.e., is not “packaged” as part of the container). Instead, dynamic code corresponds to code that can be provided and/or changed while a container instance is running. In this fashion, different instances of the same container can behave differently by executing one or more blocks of different dynamic code. Multiple iterations of dynamic code can thus be integrated in one or more instances of the same container without having to generate a new container image each time the dynamic code is changed.

In the method illustrated inFIG. 2, a first version of a container image103ais stored on image registry101. The container image103adefines a container comprising a code import module119and a code execution module121. The code import module119is configured to import code from a location that is external to the container, while the code execution module121is configured to execute at least some of the imported code within the environment of the container. As can be appreciated, external code can correspond to any code that is stored on a location external to the container, such that the code persists independent of whether the container is running or stopped. Although external code can be logically and/or physically stored outside the container, it is appreciated that the external code can be referenced, accessed and/or copied from inside the container via different mechanisms.

The container image103acan be deployed by container orchestrator105to run a first instance103a′ of the container image, in this case on a first host server107a. Once the first instance103a′ is running, the code import module119and code execution module121can operate to retrieve and execute dynamic code within the first instance103a′. In particular, code import module119can retrieve first code111a(such as a first user's code) from a first specified location, for example from a location on external code storage109. Once the first code111ais retrieved it can be executed by code execution module121, along with any fixed code that may already be present in the container image103a.The results of executing first code111acan be subsequently output, for example via a user interface and/or by creating and storing an output file or log.

At any time while the first instance103a′ is running or is stopped, the container image103acan also be deployed by container orchestrator105to run a second instance103a″ (or any number of subsequent instances) of the container image.

In the present embodiment, the second instance103a″ is run on a second host server107b,although it is appreciated that the second instance103a″ could also be run on the first host server107a.Once the second instance103a″ is running, the code import module119and code execution module121can operate to retrieve and execute dynamic code within the second instance103a″. In particular, code import module119can retrieve second code111b(such as a second user's code, or a modified version of first code111a) from a second specified location, for example from a location on external code storage109. The second specified location can be different from the first specified location or can be the same, for example if the second code111bcorresponds to a modified version of the first code111a.Once the second code111bis retrieved it can be executed by code execution module121, along with any fixed code that may already be present in the container image103a.The results of executing second code111bcan be subsequently output, for example via a user interface and/or by creating and storing an output file or log.

In the method described above, a single container image103ais used to create first103a′ and second103a″ container instances. Accordingly, the first103a′ and second103a″ instances will essentially be identical once instantiated. This can allow for first111aand second111bcode to be separately executed in identical software runtime environments as defined by the image103a,including the same operating system, runtime engines, environment variables, libraries, configurations, sources of data, etc. It is appreciated that in addition to the containers having identical software runtime environments (i.e., internal runtime environments), the host servers107aand107bcan also be configured with substantially identical runtime environments, including the same hardware and/or software configurations. This can allow for the first103a′ and second103a″ container instances to be separately run in identical external runtime environments on host servers107aand107b.

Although in the above-described example the first111aand second111bcode is executed in two separate container instances103a′,103a″, it is appreciated that in some embodiments the first111aand second111bcode can both be executed in the same container instance103a′. As an example, the code import module119on first container instance103a′ can retrieve first code111a(for example corresponding to a first version of a user's algorithm), and the first code111acan be executed by code execution module121for validation and testing. The first code111acan subsequently be modified (for example to create an updated version of the user's algorithm) to create second code111b.The code import module119on first container instance103a′ can then be operated to retrieve the second code111band overwrite and/or delete the first code111a.The second code111bcan then be executed by code execution module121for validation and testing. In this fashion, two different versions of dynamic code111aand111bcan be executed in identical runtime environments without having to expend resources running multiple container instances, and further without having to create and store multiple container images.

As mentioned above, the external code111a,111bcan be retrieved by code import module119via different mechanisms. For example, in some embodiments, the code storage109can comprise cloud storage, and the import module119can be configured to download the code111a,111bfrom the cloud storage into the container instance103a′,103a″, such as via an HTTPS request. As another example, the code storage109can comprise local or network storage that is accessible to the host server107a,107, and the container instance103a′,103a″ can be instantiated with a mounted volume that points to the local or network storage. The import module119can subsequently access the code111a,111bthrough the volume for execution and/or download/copy the code111a,111bdirectly into the container instance103a′,103a″. As can be appreciated, the location of the code111a,111bcan be defined via an argument or parameter that is provided when the container is instantiated. In some embodiments, the location can be provided after the container is instantiated, for example by providing the location to the running container via a signal or an API. In some embodiments, the location can be provided as a runtime parameter or argument to a script in the container that is configured to retrieve the code from the specified location. Of course, other configurations are also possible. For example, in some embodiments, a script can be configured to retrieve code directly from a predefined location on a local file system.

With further reference toFIG. 3, exemplary operation of code execution module121in container image103ais shown in more detail. In the illustrated embodiment, the code execution module121comprises a fixed code component123and a dynamic code component125. The fixed code123corresponds to code and/or data that is packaged as part of the container image103a.In other words, fixed code123corresponds to code that exists in a container when the container is instantiated from the container image103a.The fixed code123is the same in all new container instances created from image103a.The fixed code123can comprise code to implement at least part of a software application, such as data and/or libraries. The fixed code123can further include generic or re-usable functions or scripts that can be called (for example by code import module119) to retrieve external code and/or external data, to orchestrate execution of external code, and/or to produce output.

Dynamic code125, on the other hand, corresponds to code that can differ from one instance of the container to another. In the present embodiment, the dynamic code125is not packaged as part of the container image103a.Instead, the dynamic code125corresponds to external code that is retrieved while the container instance is running and/or during instantiation of the container. Accordingly, two instances103a′,103a″ of the same container image103acan have dynamic code components125that differ if each instance103a′,103a″ retrieves different external code.

In the present embodiment, the code execution module121first utilizes fixed code123to retrieve external data129and dynamic code125. As an example, the fixed code123can retrieve the external data129from a specified location from one or more data sources113. Similarly, the fixed code123can retrieve the dynamic code125from a specified location on external code storage109. In the present embodiment, the external data129and dynamic code125are provided in a single package131such as a ZIP file or other archive. In this fashion, the fixed code123can be directed to retrieve a single file and extract the external data129and dynamic code125from that file. It is appreciated, however, that other configurations are possible. For example, the fixed code123can be configured to retrieve external data129and dynamic code125from a plurality of specified locations, and/or in a plurality of separate packages or archives. In some embodiments, the ZIP file can be prepared in advance (i.e., prior to retrieval by fixed code123), while in other embodiments the fixed code123can send a request to an external service to assemble the external data129and dynamic code125in a package131on demand, prior to retrieving the package131.

Once the external data129and dynamic code125are retrieved, the fixed code123can cause the dynamic code125to be executed. In the present embodiment, the dynamic code125comprises a Python script. Accordingly, the code execution module121comprises a Python interpreter121, and the fixed code123causes the interpreter121to execute the dynamic code125. It is appreciated, however, that other configurations are possible. For example, a different scripting language and corresponding interpreter can be used, or a combination of different scripting languages and interpreters can be used. Alternatively, some or all of the dynamic code125can be compiled code and can be executed by the host machine directly instead of via an interpreter. As can be appreciated, upon execution by code execution module121, the dynamic code125can carry out several functions, including processing at least some of external data129and generating an output. During execution, the dynamic code125can make calls to functions provided in the fixed code123, for example by making API calls to libraries that are included as part of the fixed code123. Such libraries can, for example, be provided in a compiled language such as C++.

Following execution of dynamic code125, control flow can return to fixed code123. Fixed code123can subsequently execute other blocks of dynamic code125if desired. In some embodiments, following execution of dynamic code125, fixed code123can carry out remaining functions of the containerized application. In the present embodiment, the remaining functions comprise generating and managing an output133. As can be appreciated, the output133can be generated at least in part from output of the dynamic code125. The output133can comprise output files, such as logs, processed data, summaries, or reports, which can be stored at a specified external location on output storage115. The external location can, for example, be provided via a runtime parameter or argument when executing fixed code123. In this fashion, the output files can persist even once the container instance is stopped. Additionally, or alternatively, at least some of the output133can be provided to a user interface, such as a graphical user interface for display.

Although a particular configuration and flow of code execution module121has been described, it is appreciated that other configurations are possible. For example, in some embodiments, at least some external data129and/or external code can be retrieved by dynamic code125. Similarly, at least some output133can be managed (ex: compiled, stored, displayed, etc.) by dynamic code125. As another example, in some embodiments, at least some of fixed code123can comprise Python or other scripts and can therefore also be executed within interpreter127. Of course, many other configurations are possible. Preferably, program execution and control start via fixed code123and terminate via fixed code123.

One skilled in the art will appreciate that the above-described systems and methods can be utilized as part of an improved software development process. By way of example, and with reference toFIG. 4, an exemplary software development process200is shown according to an embodiment.

A first subprocess201can comprise creating a container. In the present embodiment, the container is configured as a testbed for executing and testing trading algorithms coded in a scripting language. Accordingly, the container can include a runtime environment suitable for executing such trading algorithms, including a plurality of libraries and configurations that can be utilized by the trading algorithms, and an interpreter for the scripting language, such as a Python interpreter. The container can further include fixed code for carrying out steps prior to and/or following the execution of the trading algorithms. As an example, the fixed code can include a code import module for retrieving the trading algorithm scripts (i.e., dynamic code) and/or relevant testing data from one or more external sources. The fixed code can further include an output module for compiling results of the trading algorithms and/or generating a summary or report therefrom. The output module can also be configured to externally store and/or display the trading algorithm results and/or reports generated therefrom. The created container can subsequently be saved as a container image and pushed to an image registry so that it can accessed by other users.

A second subprocess203can comprise creating a trading script. During this subprocess, a user can write a customized trading algorithm in a scripting language such as Python. As can be appreciated, multiple users can independently and/or concurrently work on separate trading algorithms and create their own scripts. The scripts can subsequently be stored on code storage, such as on a code repository.

A subsequent subprocess205can comprise testing the trading script. In the present embodiment, testing the trading script comprises backtesting the trading algorithm using historical data to determine whether the algorithm meets predetermined criteria (such as a minimum profitability). The container can be configured to carry out this testing by retrieving the trading script, retrieving the required historical data, and executing the trading script to operate on the historical data. The container can further be configured to process and/or analyze an output or result of the trading algorithm, for example to calculate profitability of trades.

As can be appreciated, testing of a trading script can be initiated by a user. In particular, the user can cause an instance of the testbed container to be created from the container image and can initialize or configure the testbed container to conduct the test in a desired manner. For example, the user can provide various parameters to the testbed container, including a location of the trading script to test, start and end dates of historical trading data to be used, specific stocks whose historical trading data is to be used, specific markets whose historical trading data is to be used (ex. TSX, NASDAQ, etc.), among others. Based on these parameters, the testbed container can retrieve the trading script from the specified location, retrieve the relevant historical data (ex: from an appropriate data source and within the specified date range), execute the trading script using the relevant historical data, and generate a result or output.

Once the trading script has been executed, the results can be analyzed to determine whether the script meets predefined testing criteria207. For example, it can be determined whether the backtested trading algorithm has a profitability that is above a minimum threshold. If the criteria are not satisfied, the user can modify the trading script209, for example by tweaking the algorithm to improve its effectiveness and fixing any relevant bugs. The modified trading script can subsequently be tested in the same manner as described in subprocess205, for example by creating a new instance of the testbed container to test the modified script. Alternatively, in some embodiments, the same instance of the container can be used to test the modified script.

This process of modifying and re-testing the trading algorithm can continue until the testing criteria are satisfied207. Once the algorithm is satisfactory, the algorithm can be prepared for deployment in a production environment. In particular, this can include incorporating the trading algorithm into a new container that is suitable for production209. In some embodiments, this process can involve optimizing the container, for example by re-writing or translating the trading script in a compiled language such as C++. As another example, this can involve making the production container more lightweight by removing any unused libraries or code, such as testing code and/or computational libraries that were included in the testbed container but not actually used by the final trading algorithm. An image of the optimized container can then be created and saved in a registry, and instances of the optimized container can be deployed in a production environment211.

It should be appreciated that the above-described process can allow multiple users to develop and test trading scripts concurrently and/or independently. In particular, a plurality of users can work on their own trading scripts, and each user can create a dedicated instance of the testbed container to test and validate their scripts. In some embodiments, different trading algorithms that were created by different users can ultimately be packaged in a single production container for deployment.

Although process200was described in connection with developing trading algorithms, it is appreciated that the process can apply to other cases as well. For example, a similar process can apply to developing AI models. In such cases, an AI model can be coded in a scripting language, and the testbed container can be configured to retrieve the AI model script, retrieve relevant training and test data, execute the script to train the AI model on the training data, and test the trained AI model on the test data to assess the AI model's predictive power. The AI model script can subsequently be modified and retested as required until it performs as desired, and the AI model can be rewritten in a compiled language and containerized for production. Of course, many other use cases for process200are also possible.

As can be appreciated, the above-described systems and methods can provide several advantages. In particular, the ability to re-use a container to test multiple iterations of code facilitates a rapid and efficient software development lifecycle. It also avoids having to maintain and store many different container images that would otherwise be required each time a container is modified. Although some features and advantages have been described herein, other features and advantages may become apparent to a person skilled in the art when reading the present disclosure. The invention is not limited to the embodiments described, and one skilled in the art will understand that numerous modifications can be made without departing from the scope of the invention.