1
1
use crate :: bors:: event:: BorsEvent ;
2
- use crate :: bors:: { handle_bors_event , BorsContext , BorsState } ;
2
+ use crate :: bors:: { handle_bors_global_event , handle_bors_repository_event , BorsContext } ;
3
3
use crate :: github:: api:: GithubAppState ;
4
4
use crate :: github:: webhook:: GitHubWebhook ;
5
5
use crate :: github:: webhook:: WebhookSecret ;
6
6
use crate :: utils:: logging:: LogError ;
7
+ use crate :: { BorsGlobalEvent , BorsRepositoryEvent } ;
7
8
use axum:: extract:: State ;
8
9
use axum:: http:: StatusCode ;
9
10
use axum:: response:: IntoResponse ;
@@ -17,14 +18,20 @@ use tracing::Instrument;
17
18
18
19
/// Shared server state for all axum handlers.
19
20
pub struct ServerState {
20
- webhook_sender : WebhookSender ,
21
+ repository_event_queue : mpsc:: Sender < BorsRepositoryEvent > ,
22
+ global_event_queue : mpsc:: Sender < BorsGlobalEvent > ,
21
23
webhook_secret : WebhookSecret ,
22
24
}
23
25
24
26
impl ServerState {
25
- pub fn new ( webhook_sender : WebhookSender , webhook_secret : WebhookSecret ) -> Self {
27
+ pub fn new (
28
+ repository_event_queue : mpsc:: Sender < BorsRepositoryEvent > ,
29
+ global_event_queue : mpsc:: Sender < BorsGlobalEvent > ,
30
+ webhook_secret : WebhookSecret ,
31
+ ) -> Self {
26
32
Self {
27
- webhook_sender,
33
+ repository_event_queue,
34
+ global_event_queue,
28
35
webhook_secret,
29
36
}
30
37
}
@@ -48,41 +55,88 @@ pub async fn github_webhook_handler(
48
55
State ( state) : State < ServerStateRef > ,
49
56
GitHubWebhook ( event) : GitHubWebhook ,
50
57
) -> impl IntoResponse {
51
- match state. webhook_sender . send ( event) . await {
52
- Ok ( _) => ( StatusCode :: OK , "" ) ,
53
- Err ( err) => {
54
- tracing:: error!( "Could not send webhook event: {err:?}" ) ;
55
- ( StatusCode :: INTERNAL_SERVER_ERROR , "" )
56
- }
58
+ match event {
59
+ BorsEvent :: Global ( e) => match state. global_event_queue . send ( e) . await {
60
+ Ok ( _) => ( StatusCode :: OK , "" ) ,
61
+ Err ( err) => {
62
+ tracing:: error!( "Could not send webhook global event: {err:?}" ) ;
63
+ ( StatusCode :: INTERNAL_SERVER_ERROR , "" )
64
+ }
65
+ } ,
66
+ BorsEvent :: Repository ( e) => match state. repository_event_queue . send ( e) . await {
67
+ Ok ( _) => ( StatusCode :: OK , "" ) ,
68
+ Err ( err) => {
69
+ tracing:: error!( "Could not send webhook repository event: {err:?}" ) ;
70
+ ( StatusCode :: INTERNAL_SERVER_ERROR , "" )
71
+ }
72
+ } ,
57
73
}
58
74
}
59
75
60
- type WebhookSender = mpsc:: Sender < BorsEvent > ;
61
-
62
76
/// Creates a future with a Bors process that continuously receives webhook events and reacts to
63
77
/// them.
64
78
pub fn create_bors_process (
65
79
state : GithubAppState ,
66
80
ctx : BorsContext ,
67
- ) -> ( WebhookSender , impl Future < Output = ( ) > ) {
68
- let ( tx, mut rx) = mpsc:: channel :: < BorsEvent > ( 1024 ) ;
81
+ ) -> (
82
+ mpsc:: Sender < BorsRepositoryEvent > ,
83
+ mpsc:: Sender < BorsGlobalEvent > ,
84
+ impl Future < Output = ( ) > ,
85
+ ) {
86
+ let ( repository_tx, repository_rx) = mpsc:: channel :: < BorsRepositoryEvent > ( 1024 ) ;
87
+ let ( global_tx, global_rx) = mpsc:: channel :: < BorsGlobalEvent > ( 1024 ) ;
69
88
70
89
let service = async move {
71
- let state: Arc < dyn BorsState < _ > > = Arc :: new ( state) ;
90
+ let state = Arc :: new ( state) ;
72
91
let ctx = Arc :: new ( ctx) ;
73
- while let Some ( event) = rx. recv ( ) . await {
74
- let state = state. clone ( ) ;
75
- let ctx = ctx. clone ( ) ;
76
-
77
- let span = tracing:: info_span!( "Event" ) ;
78
- tracing:: debug!( "Received event: {event:#?}" ) ;
79
- if let Err ( error) = handle_bors_event ( event, state, ctx)
80
- . instrument ( span. clone ( ) )
81
- . await
82
- {
83
- span. log_error ( error) ;
92
+ tokio:: select! {
93
+ _ = consume_repository_events( state. clone( ) , ctx. clone( ) , repository_rx) => {
94
+ tracing:: warn!( "Repository event handling process has ended" ) ;
95
+ }
96
+ _ = consume_global_events( state. clone( ) , ctx. clone( ) , global_rx) => {
97
+ tracing:: warn!( "Global event handling process has ended" ) ;
84
98
}
85
99
}
86
100
} ;
87
- ( tx, service)
101
+ ( repository_tx, global_tx, service)
102
+ }
103
+
104
+ async fn consume_repository_events (
105
+ state : Arc < GithubAppState > ,
106
+ ctx : Arc < BorsContext > ,
107
+ mut repository_rx : mpsc:: Receiver < BorsRepositoryEvent > ,
108
+ ) {
109
+ while let Some ( event) = repository_rx. recv ( ) . await {
110
+ let state = state. clone ( ) ;
111
+ let ctx = ctx. clone ( ) ;
112
+
113
+ let span = tracing:: info_span!( "RepositoryEvent" ) ;
114
+ tracing:: debug!( "Received repository event: {event:#?}" ) ;
115
+ if let Err ( error) = handle_bors_repository_event ( event, state, ctx)
116
+ . instrument ( span. clone ( ) )
117
+ . await
118
+ {
119
+ span. log_error ( error) ;
120
+ }
121
+ }
122
+ }
123
+
124
+ async fn consume_global_events (
125
+ state : Arc < GithubAppState > ,
126
+ ctx : Arc < BorsContext > ,
127
+ mut global_rx : mpsc:: Receiver < BorsGlobalEvent > ,
128
+ ) {
129
+ while let Some ( event) = global_rx. recv ( ) . await {
130
+ let state = state. clone ( ) ;
131
+ let ctx = ctx. clone ( ) ;
132
+
133
+ let span = tracing:: info_span!( "GlobalEvent" ) ;
134
+ tracing:: debug!( "Received global event: {event:#?}" ) ;
135
+ if let Err ( error) = handle_bors_global_event ( event, state, ctx)
136
+ . instrument ( span. clone ( ) )
137
+ . await
138
+ {
139
+ span. log_error ( error) ;
140
+ }
141
+ }
88
142
}
0 commit comments