Beesnest - Personal Application Server

Home Documents Downloads/Code About Contact Me

Beesnest Script Engines

Beesnest can work with any kind of scripting language, but you need to have an Engine that will connect between the interpreter and the Beesnest server. This engine should load from a dynamically linked library (Dll for Windows, sa for Linux). More on how to build a Beesnest script engine read here

Setting up a script engine

The first step to use a script engine, is to prepare the simple configuration file for it. The configuration file name has to end with .bnc and it has to be in the configuration folder of Beesnest.
A sample configuration file will look like this:
<Engines> <TestEngine> <File-Name>Engines/TestEngine/TestEngine.dll</File-Name> <Storable>yes</Storable> </TestEngine> </Engines>
Engines is the common entry for all script engines.
TestEngine Here you have to change the entry name itself. This will be the name you choose to call this script engine, and the name you will use in the pre-processed HTML files. Every script engine has to have a different name.
File-Name Is the library file (dll) where the engine is. It can be relative (to Beesnest executable) or absolute path.
Storable should be set to "yes" if you want to be able to store this script engine between pages (more below). It is relevant just if the engine supports storing.

In addition you should set at least one file type that will allow for an execution of scripts. Set the Exec entry of this file type to yes. Look at this example for details. On my server I set just files of type .bns to be executed, that way I save server resources (Note that the "#include..." command is not a script).
You can also set a file type that will go directly to a script engine. Then this file should be written in this script language. For example I set the py files to go directly to the BnPython script engine. look at the example for that as well.

Using a script engine

In a file from one of the types you set to allow script execution, you can use this script engine. use the special tag bnscript to send a piece of script to the engine. < bnscript TestEngine> ... The code to send to TestEngine ... < /bnscript> The output from the execution of this script will replace the bnscript tag and its content.

Important note about the bnscript tag: This is not a regular HTML tag. First, it is case sensitive (so BnScript won't work). Second, it will be executed also if it is in an HTML comment.

If under the Server configuration, you set the entry Default-Engine to "TestEngine", you will be able to use it as:

< bnscript> ... The code to send to TestEngine ... < /bnscript>

Script Processing Timeout

Beesnest is keeping truck of the script processing time. If it goes over the time limit, it stops the processing, and sends to the user whatever is in the buffer. The default time limit is set in the configuration files under Response-Time-Limit. You can change this value in every request using SSI as
<!--# set var = BNI_TimeLimit value = XXX --> (BNI_ is not a request variable!). Value of zero will cancel the time limit.

This feature is really making Beesnest a more complicated software (I need to run the script in a separate thread), but it is important to have some time limit.

There is also a size limit on the response buffer. in the configuration files it sets by the Response-SizeLimit, and you can change it in the same way by using BNI_SizeLimit. Also here zero will cancel the size limit. Every engine has to implement the size limit by it's own.

Response status code and sending raw data with a script

With every scripting language the commands will be a bit different, but if you set the response status code to 0, Beesnest will not send the HTTP headers at all. Then every call to Flush, or when the buffer is been sent to the client in the end of the page processing, will send just the binary data that in the buffer. the HTTP protocol will be ignored. You can use this feature to communicate with other clients than web browsers.

In addition you can set the status code to other codes than 200 (OK). To set the status code use the SetHeader command of your script engine, with a "header" name of STATUS_CODE. The code should be passed as string in the second argument. Every string that will not represent a number (like empty string) will set the code to 0. You can also get the status code by calling GetHeader with the name STATUS_CODE.

About storing a script engine

Beesnest has a special feature, it can stores a script engine, and everything loaded in it, for a logged in user. That means that a script can be execute over several pages. Like an event driven program, here an event will be a request for a page, but all the variables, functions and objects will still be there! You can continue the execution of the script exactly from the place it ended in the last page. The only different is that now the Request object will be of the current page (little more on the request object below).

As mentioned, in order to allow a script engine to be stored, you need to configure it in the configuration file of this engine. While an engine is configured to be Storable, it will be stored for a logged in user by default. If you want to release this engine use delete in the closing tag:

< bnscript TestEngine> ... The code to send to TestEngine ... < /bnscript delete>

If you want to make sure a stored engine will get released after some time it was idle, set the Engine-Time-Limit entry in the Server configuration. This time limit is in seconds, and there is one time limit for all types of engines. If this entry is missing, or it is zero, there is no time limit for the storing of an engine. it will get released just when the user releases it, or when she logs out.

Using multiple instances of an engine simultaneously

An engine can be stored just for a logged in user. Beesnest do not keep a "session" for not logged in users.

However, a logged in user can request more then one page simultaneously. A script engine instance though, can be in use just by one request (thread) at a time, and just one instance from an engine type can be stored.

If this is the case when the engine is not "Storable", there will be no problem. Every request will get it's own new instance (object) of the script engine. For a "Storable" engine though, there is no way to know which engine instance will be the stored one, and which will be the new one (the first request will get the stored engine). The same goes in the end of the script, the first engine that will get the job done, will get stored, the second one will be deleted.

Beesnest keeps track of engines (and adapters) by the name they have in the configuration files. A solution for a situation a programmer needs to use more than one instance of a script engine simultaneously, but still want to store (one of) the engines, is to define two engines that will load from the same library (Dll).

<Engines> <TestEngineA> <File-Name>Engines/TestEngine/TestEngine.dll</File-Name> <Storable>yes</Storable> </TestEngineA> <TestEngineB> <File-Name>Engines/TestEngine/TestEngine.dll</File-Name> <Storable>no</Storable> </TestEngineB> </Engines> Now, if you ask for TestEngineA you get a "Storable" version of TestEngine (and you should work just with one at a time). If you ask for TestEngineB you get an instance of TestEngine that cannot be stored. You can work with as many TestEngineBs as you want, at the same time, they will not get stored. When you execute a page that ask for TestEngineA, you know exactly what will be in it.

Just to make it clear, on the same page (Request), an engine keep its state whether it is "Storable" or not. For one page you ALWAYS get just one instance of a script engine. However, you can use more then one type of script engines in the same page.

Similar problem is when a logged in user runs two applications at the same time, and these applications want to use the same script engine, but each one want a different "Storable" instance (interpreter).

In order to ensure that each application will get it's own interpreter, the application developer has to use different names for engines that are loaded from the same library. So all the developer has to do, is to insert a new engine entry to the configuration, that will point to the same library (dll) but will have a unique name (and set Storable to yes). Then always use this name when working with this specific script engine in her application.
Like in the previous case, this is necessary just for a Storable script engines

A few words about the Request, Response and Adapters Set objects.

For every request for a page, a script engine will get a Request object and a Response object. From the request object the engine can get all the request variables (get, post, headers and variables form cookies). With the Response object the engine can set response headers, flush the response (chunk response) or clear the response buffer.
Different types of engines can communicate on the same page. If the first executed engine sets a request variable, the second engine will be able to read it.

Finally, if the user is logged in, the engine will get also an AdaptersSet object, for this user. Adapters are pieces of program that can do something, almost everything a programmer whats to do with an adapter, he can do. Just store some data, execute some logic, communicate with other software or devices and so on. With the AdaptersSet object the engine can create new adapters, read and write from adapters, and delete adapters. Adapter, once created, stay loaded for the user until he release them, logged out, or a timeout limit is reached (here the timeout limit is set for each adapter separately).

The exact way to use the Request, Response and AdaptersSet object, is depended on the specific script engine. It cannot be documented here, it should be documented with the engine itself.

Home Documents Downloads/Code About Contact Me