@@ -7,7 +7,9 @@ import org.eclipse.egit.github.core.service.RepositoryService
77import org.eclipse.egit.github.core.service.UserService
88import org.eclipse.egit.github.core.service.WatcherService
99import org.slf4j.LoggerFactory
10- import java.util.*
10+ import java.io.IOException
11+ import java.util.concurrent.ConcurrentHashMap
12+ import java.util.concurrent.Executors
1113import java.util.concurrent.TimeUnit
1214
1315object GhService {
@@ -16,8 +18,11 @@ object GhService {
1618
1719 private val log = LoggerFactory .getLogger(GhService .javaClass)
1820
21+ // Allows for parallel iteration and O(1) put/remove
22+ private val clientSessions = ConcurrentHashMap <WsSession , Boolean >()
23+
1924 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 ) } }
2126 private val repoServices = clients.map { RepositoryService (it) }
2227 private val commitServices = clients.map { CommitService (it) }
2328 private val userServices = clients.map { UserService (it) }
@@ -30,9 +35,15 @@ object GhService {
3035
3136 val remainingRequests: Int get() = clients.sumBy { it.remainingRequests }
3237
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({
3647 repoServices.forEach {
3748 try {
3849 it.getRepository(" tipsy" , " github-profile-summary" )
@@ -41,18 +52,22 @@ object GhService {
4152 log.info(" Pinged client ${clients.indexOf(it.client)} - was rate-limited" )
4253 }
4354 }
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 )
4769
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()
5470 }
5571 }
5672
5773}
58-
0 commit comments