# eXtremeDB Cluster Applications in C#

> To implement a cluster with C#, first an array of Cluster nodes is initialized and passed to the `ClusterDatabase.Open()` method, then a ClusterConnection is instantiated for this database and a Listener thread is created. Finally the `ClusterConnection.Stop()` method is called to terminate the Cluster session. The following code snippet demonstrates how a simple Cluster C# application performs these steps:

>         public class Cluster
>         {
>             Database db;
>             // listen thread
>             public void ClusterListen()
>             {
>                 ClusterConnection con = new ClusterConnection(db);
>                 con.Listen();

>                 con.Disconnect();
>             }

>             public static long msec()
>             {
>                 return DateTime.Now.Ticks / 10000;
>             }

>             private bool checkQuorum(int[] neighbourIds)
>             {
>                 Console.Write("Checking quorum. Neighbours are:");
>                 foreach (int nid in neighbourIds)
>                 {
>                     Console.Write("{0} ", nid);
>                 }
>                 Console.WriteLine("Return {0}", true);
>                 return true;
>             }

>             public bool CheckFunc(int[] neighbourIds) // for delegate call
>             {
>                 bool result = true;
>                 // logic to determine if nodes can access my_data
>                 return result;
>             }

>             public static void Main(String[] args)
>             {
>                 new Cluster(Int32.Parse(args[0]), Int32.Parse(args[1]));
>             }

>             Cluster(int n_nodes, int node_id)
>             {
>                 Database.Parameters parameters = new Database.Parameters();
>                 parameters.MemPageSize = PAGE_SIZE;
>                 parameters.Classes = new Type[]{typeof(Record)};
>                 Database.ClusterNodeParams[] node_params = new
>                 Database.ClusterNodeParams[n_nodes];

>                 for (int i = 0; i < n_nodes; ++i)
>                 {
>                     //use different ports on the localhost
>                     node_params[i].Addr = "127.0.0.1:200" + (10 + i * 10);
>                     node_params[i].QRank = 1;
>                 }

>                 // set cluster parameters - nodes and window length
>                 parameters.ClusterParameters = new Database.ClusterParams( node_params,

>                                                 node_id );

>                 parameters.ClusterParameters.Window.Length = WINDOW_LENGTH;

>                 // create delegate and assign the member function
>                 CheckQuorum checkQ = new CheckQuorum();
>                 checkQ.my_data = 119; // set user context
>                 parameters.ClusterParameters.QuorumDelegate = new
>                 Database.ClusterQuorumDelegate(checkQ.CheckFunc);

>                 db = new Database(new ExtremedbWrapper(), Database.Mode.ClusterSupport);

>                 db.Open("cluster-db", parameters, DATABASE_SIZE);

>                 //start cluster listener thread
>                 Thread listenThread = new Thread(new ThreadStart(ClusterListen));
>                 listenThread.Start();
>                 // connect to the database using ClusterConnection

>                 ClusterConnection con = new ClusterConnection(db);

>                 // do operations on the database

>                 con.Stop(); // stop cluster runtime. Returns after ALL nodes call Stop()
>                 listenThread.Join();  // wait for listener thread

>                 con.Disconnect();
>                 db.Close();
>             }
>         }

> Note that the Cluster runtime is started in the Database constructor. Note also the use of `CheckQuorum` delegate that allows the application to validate the collection of nodes online to determine if the cluster can begin processing.