forked from facebook/watchman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwatchman_client.h
136 lines (110 loc) · 4.04 KB
/
watchman_client.h
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
134
135
136
/* Copyright 2012-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0 */
#pragma once
#include <folly/Synchronized.h>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include "Logging.h"
#include "watchman_pdu.h"
#include "watchman_perf.h"
struct w_query;
struct w_query_res;
struct watchman_client_subscription;
namespace watchman {
enum ClientStateDisposition {
PendingEnter,
Asserted,
PendingLeave,
Done,
};
class ClientStateAssertion {
public:
const std::shared_ptr<w_root_t> root; // Holds a ref on the root
const w_string name;
// locking: You must hold root->assertedStates lock to access this member
ClientStateDisposition disposition{PendingEnter};
// Deferred payload to send when this assertion makes it to the front
// of the queue.
// locking: You must hold root->assertedStates lock to access this member.
json_ref enterPayload;
ClientStateAssertion(
const std::shared_ptr<w_root_t>& root,
const w_string& name)
: root(root), name(name) {}
};
} // namespace watchman
struct watchman_client : public std::enable_shared_from_this<watchman_client> {
std::unique_ptr<watchman_stream> stm;
std::unique_ptr<watchman_event> ping;
w_jbuffer_t reader, writer;
bool client_mode{false};
bool client_is_owner{false};
enum w_pdu_type pdu_type;
uint32_t capabilities;
// The command currently being processed by dispatch_command
json_ref current_command;
w_perf_t* perf_sample{nullptr};
// Queue of things to send to the client.
std::deque<json_ref> responses;
// Logging Subscriptions
std::shared_ptr<watchman::Publisher::Subscriber> debugSub;
std::shared_ptr<watchman::Publisher::Subscriber> errorSub;
watchman_client();
explicit watchman_client(std::unique_ptr<watchman_stream>&& stm);
virtual ~watchman_client();
void enqueueResponse(json_ref&& resp, bool ping = true);
};
struct watchman_user_client;
enum class OnStateTransition { QueryAnyway, DontAdvance };
struct watchman_client_subscription
: public std::enable_shared_from_this<watchman_client_subscription> {
std::shared_ptr<w_root_t> root;
w_string name;
/* whether this subscription is paused */
bool debug_paused = false;
std::shared_ptr<w_query> query;
bool vcs_defer;
uint32_t last_sub_tick{0};
// map of statename => bool. If true, policy is drop, else defer
std::unordered_map<w_string, bool> drop_or_defer;
std::weak_ptr<watchman_client> weakClient;
explicit watchman_client_subscription(
const std::shared_ptr<w_root_t>& root,
std::weak_ptr<watchman_client> client);
~watchman_client_subscription();
void processSubscription();
std::shared_ptr<watchman_user_client> lockClient();
json_ref buildSubscriptionResults(
const std::shared_ptr<w_root_t>& root,
ClockSpec& position,
OnStateTransition onStateTransition);
private:
ClockSpec runSubscriptionRules(
watchman_user_client* client,
const std::shared_ptr<w_root_t>& root);
void updateSubscriptionTicks(w_query_res* res);
void processSubscriptionImpl();
};
// Represents the server side session maintained for a client of
// the watchman per-user process
struct watchman_user_client : public watchman_client {
/* map of subscription name => struct watchman_client_subscription */
std::unordered_map<w_string, std::shared_ptr<watchman_client_subscription>>
subscriptions;
/* map of state-name => ClientStateAssertion
* The values are owned by root::assertedStates */
std::unordered_map<w_string, std::weak_ptr<watchman::ClientStateAssertion>>
states;
// Subscriber to root::unilateralResponses
std::unordered_map<
std::shared_ptr<watchman_client_subscription>,
std::shared_ptr<watchman::Publisher::Subscriber>>
unilateralSub;
explicit watchman_user_client(std::unique_ptr<watchman_stream>&& stm);
~watchman_user_client() override;
bool unsubByName(const w_string& name);
};
extern folly::Synchronized<std::unordered_set<std::shared_ptr<watchman_client>>>
clients;
void w_client_vacate_states(struct watchman_user_client* client);