Developers Documentation

×

Warning

301 error for file:https://clearos.com/dokuwiki2/lib/exe/css.php?t=dokuwiki&tseed=82873f9c9a1f5784b951644363f20ef8

User Tools

Site Tools


Stateless Libraries

One of the design goals of ClearOS is to provide a software API that can be accessed from across the network. Typically, this is done through REST, XML RPC or SOAP. Regardless of the remote access implementation, it is important to build your ClearOS libraries with this design goal in mind. The litmus test is simple - any method call in your library should not have to depend on the state of the class. In other words, your library should be stateless.

Stateful Versus Stateless

We are going to use OpenVPN as an example. The webconfig page will need to display some configuration options available in OpenVPN, namely:

  • Domain, e.g. example.com
  • DNS server, e.g. 192.168.1.1

The client code in the webconfig page will look something like the following:

// Create OpenVPN object
$openvpn = new OpenVPN();
 
// Load Configuration 
$domain = $openvpn->GetDomain();
$dns = $openvpn->GetDnsServer();
 
// Save Configuration
$openvpn->SetDomain('example.com');
$openvpn->SetDnsServer('1.2.3.4');
$openvpn->SaveConfiguration();

Stateful Implementation

In our stateful example, the entire OpenVPN configuration is loaded into the $this→config array - a class variable. With the configuration preloaded, the GetX methods merely have to return the corresponding array element. The general framework for this stateful example is shown below.

class OpenVpn extends Daemon
{
    protected $config = array();
 
    public function __construct()
    {
        $this->_LoadConfiguration();
    }
 
    public function GetDomain()
    {
        return $this->config['domain'];
    }
 
    public function GetDnsServer()
    {
        return $this->config['dns'];
    }
 
    public function SetDomain($domain)
    {
        $this->config['domain'] = $domain;
    }
 
    public function SetDnsServer($dns)
    {
        $this->config['dns'] = $dns;
    }
 
    public function SaveConfiguration()
    {
        ... save the configuration based on $this->config array...
    }
 
    private function _LoadConfiguration()
    {
        ... load the configuration into $this->config array...
    }
}

This approach is certainly efficient and does the job well. However, the SaveConfiguration() method depends on preserving the state from the SetDomain() and SetDnsServer() calls. Even loading the configuration in the class constructor is problematic in some scenarios.

Stateless Implementation

To transform this class into a stateless implementation, each method call needs to be independent of other methods and class variables.

class OpenVpn extends Daemon
{
    protected $config = array();
 
    public function __construct()
    {}
 
    public function GetDomain()
    {
        $this->_LoadConfiguration();
        return $this->config['domain'];
    }
 
    public function GetDnsServer()
    {
        $this->_LoadConfiguration();
        return $this->config['dns'];
    }
 
    public function SetDomain($domain)
    {
        $this->config['domain'] = $domain;
        $this->_SaveConfiguration();
    }
 
    public function SetDnsServer($dns)
    {
        $this->config['dns'] = $dns;
        $this->_SaveConfiguration();
    }
 
    private function _SaveConfiguration()
    {
        ... save the configuration based on $this->config array...
    }
 
    private function _LoadConfiguration()
    {
        ... load the configuration into $this->config array...
    }
}

Well that didn't turn out to look too different. The downside with this implementation is the inefficiencies. The configuration file is loaded on every GetX method, and saved on every SetX method.

content/en_us/dev_framework_reference_guide_stateless_libraries.txt · Last modified: 2015/02/05 20:23 (external edit)

https://clearos.com/dokuwiki2/lib/exe/indexer.php?id=content%3Aen_us%3Adev_framework_reference_guide_stateless_libraries&1710828086