summaryrefslogtreecommitdiff
path: root/jstests/concurrency/fsm_example.js
blob: a112195e1a401a6337d47295de03eae4e1ad0612 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
'use strict';

/**
 * fsm_example.js
 *
 * Includes documentation of each property on $config.
 * Serves as a template for new workloads.
 */
var $config = (function() {

    // 'data' is passed (copied) to each of the worker threads.
    var data = {};

    // 'states' are the different functions callable by a worker
    // thread. The 'this' argument of any exposed function is
    // bound as '$config.data'.
    var states = {
        init: function init(db, collName) {
            this.start = 10 * this.tid;
        },

        scanGT: function scanGT(db, collName) {
            db[collName].find({ _id: { $gt: this.start } }).itcount();
        },

        scanLTE: function scanLTE(db, collName) {
            db[collName].find({ _id: { $lte: this.start } }).itcount();
        },
    };

    // 'transitions' defines how the FSM should proceed from its
    // current state to the next state. The value associated with a
    // particular state represents the likelihood of that transition.
    //
    // For example, 'init: { scanGT: 0.5, scanLTE: 0.5 }' means that
    // the worker thread will transition from the 'init' state
    //   to the 'scanGT'  state with probability 0.5, and
    //   to the 'scanLTE' state with probability 0.5.
    //
    // All state functions should appear as keys within 'transitions'.
    var transitions = {
        init:    { scanGT: 0.5, scanLTE: 0.5 },
        scanGT:  { scanGT: 0.8, scanLTE: 0.2 },
        scanLTE: { scanGT: 0.2, scanLTE: 0.8 }
    };

    // 'setup' is run once by the parent thread after the cluster has
    // been initialized, but before the worker threads have been spawned.
    // The 'this' argument is bound as '$config.data'. 'cluster' is provided
    // to allow execution against all mongos and mongod nodes.
    function setup(db, collName, cluster) {
        // Workloads should NOT drop the collection db[collName], as
        // doing so is handled by runner.js before 'setup' is called.
        for (var i = 0; i < 1000; ++i) {
            db[collName].insert({ _id: i });
        }

        cluster.executeOnMongodNodes(function(db) {
            printjson(db.serverCmdLineOpts());
        });

        cluster.executeOnMongosNodes(function(db) {
            printjson(db.serverCmdLineOpts());
        });
    }

    // 'teardown' is run once by the parent thread before the cluster
    // is destroyed, but after the worker threads have been reaped.
    // The 'this' argument is bound as '$config.data'. 'cluster' is provided
    // to allow execution against all mongos and mongod nodes.
    function teardown(db, collName, cluster) {}

    return {
        threadCount: 5,
        iterations: 10,
        startState: 'init',        // optional, default 'init'
        states: states,
        transitions: transitions,
        setup: setup,              // optional, default empty function
        teardown: teardown,        // optional, default empty function
        data: data                 // optional, default empty object
    };

})();