@@ -7,7 +7,9 @@ import org.eclipse.egit.github.core.service.RepositoryService
7
7
import org.eclipse.egit.github.core.service.UserService
8
8
import org.eclipse.egit.github.core.service.WatcherService
9
9
import org.slf4j.LoggerFactory
10
- import java.util.*
10
+ import java.io.IOException
11
+ import java.util.concurrent.ConcurrentHashMap
12
+ import java.util.concurrent.Executors
11
13
import java.util.concurrent.TimeUnit
12
14
13
15
object GhService {
@@ -16,8 +18,11 @@ object GhService {
16
18
17
19
private val log = LoggerFactory .getLogger(GhService .javaClass)
18
20
21
+ // Allows for parallel iteration and O(1) put/remove
22
+ private val clientSessions = ConcurrentHashMap <WsSession , Boolean >()
23
+
19
24
private val tokens = Config .getApiTokens()?.split(" ," ) ? : listOf (" " ) // empty token is limited to 60 requests
20
- private val clients = tokens.map { token -> GitHubClient ().apply { setOAuth2Token(token ) } }
25
+ private val clients = tokens.map { GitHubClient ().apply { setOAuth2Token(it ) } }
21
26
private val repoServices = clients.map { RepositoryService (it) }
22
27
private val commitServices = clients.map { CommitService (it) }
23
28
private val userServices = clients.map { UserService (it) }
@@ -30,9 +35,15 @@ object GhService {
30
35
31
36
val remainingRequests: Int get() = clients.sumBy { it.remainingRequests }
32
37
33
- init { // create timer to ping clients every other minute to make sure remainingRequests is correct
34
- Timer ().scheduleAtFixedRate(object : TimerTask () {
35
- override fun run () {
38
+ fun registerClient (ws : WsSession ) = clientSessions.put(ws, true ) == true
39
+
40
+ fun unregisterClient (ws : WsSession ) = clientSessions.remove(ws) == true
41
+
42
+ init {
43
+ Executors .newScheduledThreadPool(2 ).apply {
44
+
45
+ // ping clients every other minute to make sure remainingRequests is correct
46
+ scheduleAtFixedRate({
36
47
repoServices.forEach {
37
48
try {
38
49
it.getRepository(" tipsy" , " github-profile-summary" )
@@ -41,18 +52,22 @@ object GhService {
41
52
log.info(" Pinged client ${clients.indexOf(it.client)} - was rate-limited" )
42
53
}
43
54
}
44
- }
45
- }, 0 , TimeUnit .MILLISECONDS .convert(2 , TimeUnit .MINUTES ))
46
- }
55
+ }, 0 , 2 , TimeUnit .MINUTES )
56
+
57
+ // update all connected clients with remainingRequests twice per second
58
+ scheduleAtFixedRate({
59
+ val payload = remainingRequests.toString()
60
+ clientSessions.forEachKey(1 ) {
61
+ try {
62
+ if (it.isOpen)
63
+ it.send(payload)
64
+ } catch (e: IOException ) {
65
+ log?.error(e.toString())
66
+ }
67
+ }
68
+ }, 0 , 500 , TimeUnit .MILLISECONDS )
47
69
48
- fun broadcastRemainingRequests (session : WsSession ) = object : TimerTask () {
49
- override fun run () {
50
- if (session.isOpen) {
51
- return session.send(GhService .remainingRequests.toString())
52
- }
53
- this .cancel()
54
70
}
55
71
}
56
72
57
73
}
58
-
0 commit comments