summaryrefslogtreecommitdiffstats
path: root/src/mgr/StandbyPyModules.h
blob: 501dfc8c7e408ad7392c3a7067ace6668ad3b184 (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2016 John Spray <john.spray@redhat.com>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 */

#pragma once

#include <string>
#include <map>

#include <Python.h>

#include "common/Thread.h"
#include "common/ceph_mutex.h"

#include "mgr/Gil.h"
#include "mon/MonClient.h"
#include "mon/MgrMap.h"
#include "mgr/PyModuleRunner.h"

class Finisher;

/**
 * State that is read by all modules running in standby mode
 */
class StandbyPyModuleState
{
  mutable ceph::mutex lock = ceph::make_mutex("StandbyPyModuleState::lock");

  MgrMap mgr_map;
  PyModuleConfig &module_config;
  MonClient &monc;

public:

  
  StandbyPyModuleState(PyModuleConfig &module_config_, MonClient &monc_)
    : module_config(module_config_), monc(monc_)
  {}

  void set_mgr_map(const MgrMap &mgr_map_)
  {
    std::lock_guard l(lock);

    mgr_map = mgr_map_;
  }

  // MonClient does all its own locking so we're happy to hand out
  // references.
  MonClient &get_monc() {return monc;};

  template<typename Callback, typename...Args>
  void with_mgr_map(Callback&& cb, Args&&...args) const
  {
    std::lock_guard l(lock);
    std::forward<Callback>(cb)(mgr_map, std::forward<Args>(args)...);
  }

  template<typename Callback, typename...Args>
  auto with_config(Callback&& cb, Args&&... args) const ->
    decltype(cb(module_config, std::forward<Args>(args)...)) {
    std::lock_guard l(lock);

    return std::forward<Callback>(cb)(module_config, std::forward<Args>(args)...);
  }
};


class StandbyPyModule : public PyModuleRunner
{
  StandbyPyModuleState &state;

  public:

  StandbyPyModule(
      StandbyPyModuleState &state_,
      const PyModuleRef &py_module_,
      LogChannelRef clog_)
    :
      PyModuleRunner(py_module_, clog_),
      state(state_)
  {
  }

  bool get_config(const std::string &key, std::string *value) const;
  bool get_store(const std::string &key, std::string *value) const;
  std::string get_active_uri() const;
  entity_addrvec_t get_myaddrs() const {
    return state.get_monc().get_myaddrs();
  }

  int load();
};

class StandbyPyModules
{
private:
  mutable ceph::mutex lock = ceph::make_mutex("StandbyPyModules::lock");
  std::map<std::string, std::unique_ptr<StandbyPyModule>> modules;

  StandbyPyModuleState state;

  LogChannelRef clog;

  Finisher &finisher;

public:

  StandbyPyModules(
      const MgrMap &mgr_map_,
      PyModuleConfig &module_config,
      LogChannelRef clog_,
      MonClient &monc,
      Finisher &f);

  void start_one(PyModuleRef py_module);

  void shutdown();

  void handle_mgr_map(const MgrMap &mgr_map)
  {
    state.set_mgr_map(mgr_map);
  }

};