Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
150
Issues
150
List
Board
Labels
Milestones
Merge Requests
5
Merge Requests
5
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
19f4848f
Verified
Commit
19f4848f
authored
Sep 03, 2024
by
Przemyslaw Kaminski
1
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'adinapoli/issue-392' into 304-dev-toml-config-rewrite
parents
1e1396c4
3e8ebc35
Pipeline
#6571
failed with stages
in 13 minutes and 14 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
143 additions
and
42 deletions
+143
-42
Main.hs
bin/gargantext-central-exchange/Main.hs
+81
-0
cabal.project
cabal.project
+3
-2
EnvTypes.hs
src/Gargantext/API/Admin/EnvTypes.hs
+3
-2
Settings.hs
src/Gargantext/API/Admin/Settings.hs
+1
-1
CentralExchange.hs
src/Gargantext/Core/AsyncUpdates/CentralExchange.hs
+6
-3
Dispatcher.hs
src/Gargantext/Core/AsyncUpdates/Dispatcher.hs
+26
-8
Types.hs
src/Gargantext/Core/AsyncUpdates/Dispatcher/Types.hs
+2
-9
WebSocket.hs
src/Gargantext/Core/AsyncUpdates/Dispatcher/WebSocket.hs
+4
-3
stack.yaml
stack.yaml
+4
-0
Main.hs
test/drivers/hspec/Main.hs
+13
-14
No files found.
bin/gargantext-central-exchange/Main.hs
0 → 100644
View file @
19f4848f
{-|
Module : Main.hs
Description : Gargantext central exchange for async notifications
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
{-# LANGUAGE Strict #-}
module
Main
where
import
Control.Concurrent
(
threadDelay
)
import
Control.Monad
(
join
,
mapM_
)
import
Data.ByteString.Char8
qualified
as
C
import
Data.Text
qualified
as
T
import
Gargantext.Core.AsyncUpdates.CentralExchange
(
gServer
)
import
Gargantext.Core.AsyncUpdates.Constants
(
ceBind
,
ceConnect
)
import
Gargantext.Prelude
import
Nanomsg
import
Options.Applicative
data
Command
=
CEServer
|
SimpleServer
|
WSServer
|
Client
parser
::
Parser
(
IO
()
)
parser
=
subparser
(
command
"ce-server"
(
info
(
pure
gServer
)
idm
)
<>
command
"simple-server"
(
info
(
pure
simpleServer
)
idm
)
<>
command
"ws-server"
(
info
(
pure
wsServer
)
idm
)
<>
command
"client"
(
info
(
pure
gClient
)
idm
)
)
main
::
IO
()
main
=
join
$
execParser
(
info
parser
idm
)
simpleServer
::
IO
()
simpleServer
=
do
withSocket
Pull
$
\
s
->
do
_
<-
bind
s
ceBind
putText
"[simpleServer] receiving"
forever
$
do
mr
<-
recv
s
C
.
putStrLn
mr
-- case mr of
-- Nothing -> pure ()
-- Just r -> C.putStrLn r
-- threadDelay 10000
wsServer
::
IO
()
wsServer
=
do
withSocket
Pull
$
\
ws
->
do
_
<-
bind
ws
"ws://*:5560"
forever
$
do
putText
"[wsServer] receiving"
r
<-
recv
ws
C
.
putStrLn
r
gClient
::
IO
()
gClient
=
do
withSocket
Push
$
\
s
->
do
_
<-
connect
s
ceConnect
-- let str = C.unwords (take 10 $ repeat "hello")
let
str
=
"{
\"
type
\"
:
\"
update_tree_first_level
\"
,
\"
node_id
\"
: -1}"
C
.
putStrLn
$
C
.
pack
"sending: "
<>
str
send
s
str
withSocket
Push
$
\
s
->
do
_
<-
connect
s
ceConnect
let
str2
=
"{
\"
type
\"
:
\"
update_tree_first_level
\"
,
\"
node_id
\"
: -2}"
C
.
putStrLn
$
C
.
pack
"sending: "
<>
str2
send
s
str2
cabal.project
View file @
19f4848f
...
...
@@ -165,10 +165,11 @@ source-repository-package
location
:
https
://
github
.
com
/
robstewart57
/
rdf4h
.
git
tag
:
4f
d2edf30c141600ffad6d730cc4c1c08a6dbce4
--
FIXME
(
adn
)
Compat
-
shim
while
we
wait
for
upstream
to
catch
-
up
source
-
repository
-
package
type
:
git
location
:
https
://
github
.
com
/
garganscript
/
nanomsg
-
haskell
tag
:
23
be4130804d86979eaee5caffe323a1c7f2b0d
6
location
:
https
://
github
.
com
/
adinapoli
/
nanomsg
-
haskell
tag
:
f54fe61f06685c5af95ddff782e139d8d4e2618
6
--
source
-
repository
-
package
--
type
:
git
...
...
src/Gargantext/API/Admin/EnvTypes.hs
View file @
19f4848f
...
...
@@ -40,7 +40,8 @@ import Gargantext.API.Job
import
Gargantext.API.Prelude
(
GargM
,
IsGargServer
)
import
Gargantext.Core.AsyncUpdates.CentralExchange
qualified
as
CE
import
Gargantext.Core.AsyncUpdates.CentralExchange.Types
qualified
as
CET
import
Gargantext.Core.AsyncUpdates.Dispatcher.Types
(
Dispatcher
,
HasDispatcher
(
..
))
import
Gargantext.Core.AsyncUpdates.Dispatcher
(
Dispatcher
)
import
Gargantext.Core.AsyncUpdates.Dispatcher.Types
(
HasDispatcher
(
..
))
import
Gargantext.Core.Mail.Types
(
HasMail
,
mailSettings
)
import
Gargantext.Core.NLP
(
NLPServerMap
,
HasNLPServer
(
..
))
import
Gargantext.Core.NodeStory
...
...
@@ -161,7 +162,7 @@ instance HasMail Env where
instance
HasNLPServer
Env
where
nlpServer
=
env_nlp
instance
HasDispatcher
Env
where
instance
HasDispatcher
Env
Dispatcher
where
hasDispatcher
=
env_dispatcher
instance
Servant
.
Job
.
Core
.
HasEnv
Env
(
Job
JobLog
JobLog
)
where
...
...
src/Gargantext/API/Admin/Settings.hs
View file @
19f4848f
...
...
@@ -208,7 +208,7 @@ newEnv logger port settingsFile@(SettingsFile sf) = do
!
jobs_env
<-
Jobs
.
newJobEnv
jobs_settings
prios'
manager_env
!
central_exchange
<-
forkIO
$
CE
.
gServer
(
_gc_notifications_config
config_env
)
!
dispatcher
<-
D
.
d
ispatcher
(
_gc_notifications_config
config_env
)
!
dispatcher
<-
D
.
newD
ispatcher
(
_gc_notifications_config
config_env
)
{- An 'Env' by default doesn't have strict fields, but when constructing one in production
we want to force them to WHNF to avoid accumulating unnecessary thunks.
...
...
src/Gargantext/Core/AsyncUpdates/CentralExchange.hs
View file @
19f4848f
...
...
@@ -14,7 +14,10 @@ https://dev.sub.gargantext.org/#/share/Notes/187918
-}
module
Gargantext.Core.AsyncUpdates.CentralExchange
where
module
Gargantext.Core.AsyncUpdates.CentralExchange
(
gServer
,
notify
)
where
import
Control.Concurrent.Async
qualified
as
Async
import
Control.Concurrent.STM.TChan
qualified
as
TChan
...
...
@@ -26,7 +29,7 @@ import Gargantext.Core.AsyncUpdates.CentralExchange.Types
import
Gargantext.Core.Config.Types
(
NotificationsConfig
(
..
))
import
Gargantext.Prelude
import
Gargantext.System.Logging
(
LogLevel
(
..
),
withLogger
,
logMsg
)
import
Nanomsg
(
Pull
(
..
),
Push
(
..
),
bind
,
connect
,
recv
Malloc
,
send
,
withSocket
)
import
Nanomsg
(
Pull
(
..
),
Push
(
..
),
bind
,
connect
,
recv
,
send
,
withSocket
)
{-
...
...
@@ -58,7 +61,7 @@ gServer (NotificationsConfig { .. }) = do
withLogger
()
$
\
ioLogger
->
do
forever
$
do
-- putText "[central_exchange] receiving"
r
<-
recv
Malloc
s
4096
r
<-
recv
s
logMsg
ioLogger
INFO
$
"[central_exchange] received: "
<>
show
r
-- C.putStrLn $ "[central_exchange] " <> r
atomically
$
TChan
.
writeTChan
tChan
r
...
...
src/Gargantext/Core/AsyncUpdates/Dispatcher.hs
View file @
19f4848f
...
...
@@ -16,7 +16,14 @@ https://dev.sub.gargantext.org/#/share/Notes/187918
{-# LANGUAGE TypeOperators #-}
module
Gargantext.Core.AsyncUpdates.Dispatcher
where
module
Gargantext.Core.AsyncUpdates.Dispatcher
(
Dispatcher
-- opaque
,
newDispatcher
,
terminateDispatcher
-- * Querying a dispatcher
,
dispatcherSubscriptions
)
where
import
Control.Concurrent.Async
qualified
as
Async
import
Control.Concurrent.STM.TChan
qualified
as
TChan
...
...
@@ -30,7 +37,7 @@ import Gargantext.Core.AsyncUpdates.Dispatcher.Types
import
Gargantext.Core.Config.Types
(
NotificationsConfig
(
..
))
import
Gargantext.Prelude
import
Gargantext.System.Logging
(
LogLevel
(
DEBUG
),
withLogger
,
logMsg
)
import
Nanomsg
(
Pull
(
..
),
bind
,
recv
Malloc
,
withSocket
)
import
Nanomsg
(
Pull
(
..
),
bind
,
recv
,
withSocket
)
import
Network.WebSockets
qualified
as
WS
import
Servant.Job.Types
(
JobStatus
(
_job_id
))
import
StmContainers.Set
qualified
as
SSet
...
...
@@ -43,10 +50,21 @@ Dispatcher is a service, which provides couple of functionalities:
- dispatches these messages to connected users
-}
dispatcher
::
NotificationsConfig
->
IO
Dispatcher
dispatcher
nc
=
do
data
Dispatcher
=
Dispatcher
{
d_subscriptions
::
SSet
.
Set
Subscription
-- , d_ws_server :: WSAPI AsServer
,
d_ce_listener
::
ThreadId
}
terminateDispatcher
::
Dispatcher
->
IO
()
terminateDispatcher
=
killThread
.
d_ce_listener
dispatcherSubscriptions
::
Dispatcher
->
SSet
.
Set
Subscription
dispatcherSubscriptions
=
d_subscriptions
newDispatcher
::
NotificationsConfig
->
IO
Dispatcher
newDispatcher
nc
=
do
subscriptions
<-
SSet
.
newIO
-- let server = wsServer authSettings subscriptions
...
...
@@ -78,7 +96,7 @@ dispatcherListener (NotificationsConfig { _nc_dispatcher_bind }) subscriptions =
void
$
Async
.
concurrently
(
Async
.
replicateConcurrently
5
$
worker
tChan
throttleTChan
)
$
do
forever
$
do
-- putText "[dispatcher_listener] receiving"
r
<-
recv
Malloc
s
1024
r
<-
recv
s
-- C.putStrLn $ "[dispatcher_listener] " <> r
atomically
$
TChan
.
writeTChan
tChan
r
where
...
...
@@ -136,8 +154,8 @@ sendDataMessageThrottled (conn, msg) =
-- CETypes.CEMessage.
-- For example, we can add CEMessage.Broadcast to propagate a
-- notification to all connections.
filterCEMessageSubs
::
CETypes
.
CEMessage
->
[
Subscription
]
->
[
Subscription
]
filterCEMessageSubs
ceMessage
subscriptions
=
filter
(
ceMessageSubPred
ceMessage
)
subscriptions
_
filterCEMessageSubs
::
CETypes
.
CEMessage
->
[
Subscription
]
->
[
Subscription
]
_
filterCEMessageSubs
ceMessage
subscriptions
=
filter
(
ceMessageSubPred
ceMessage
)
subscriptions
ceMessageSubPred
::
CETypes
.
CEMessage
->
Subscription
->
Bool
ceMessageSubPred
(
CETypes
.
UpdateJobProgress
js
)
(
Subscription
{
s_topic
})
=
...
...
src/Gargantext/Core/AsyncUpdates/Dispatcher/Types.hs
View file @
19f4848f
...
...
@@ -200,15 +200,8 @@ instance ToJSON WSRequest where
,
"token"
.=
token
]
toJSON
WSDeauthorize
=
Aeson
.
object
[
"request"
.=
(
"deauthorize"
::
Text
)
]
data
Dispatcher
=
Dispatcher
{
d_subscriptions
::
SSet
.
Set
Subscription
-- , d_ws_server :: WSAPI AsServer
,
d_ce_listener
::
ThreadId
}
class
HasDispatcher
env
where
hasDispatcher
::
Getter
env
Dispatcher
class
HasDispatcher
env
dispatcher
where
hasDispatcher
::
Getter
env
dispatcher
-- | A notification is sent to clients who subscribed to specific topics
...
...
src/Gargantext/Core/AsyncUpdates/Dispatcher/WebSocket.hs
View file @
19f4848f
...
...
@@ -27,6 +27,7 @@ import Gargantext.API.Admin.Types (HasSettings(settings), Settings, jwtSettings)
import
Gargantext.API.Prelude
(
IsGargServer
)
import
Gargantext.Core.AsyncUpdates.Dispatcher.Subscriptions
import
Gargantext.Core.AsyncUpdates.Dispatcher.Types
import
Gargantext.Core.AsyncUpdates.Dispatcher
(
Dispatcher
,
dispatcherSubscriptions
)
import
Gargantext.Prelude
import
Gargantext.System.Logging
(
LogLevel
(
DEBUG
),
logMsg
,
withLogger
)
import
Network.WebSockets
qualified
as
WS
...
...
@@ -42,15 +43,15 @@ newtype WSAPI mode = WSAPI {
}
deriving
Generic
wsServer
::
(
IsGargServer
env
err
m
,
HasDispatcher
env
,
HasSettings
env
)
=>
WSAPI
(
AsServerT
m
)
wsServer
::
(
IsGargServer
env
err
m
,
HasDispatcher
env
Dispatcher
,
HasSettings
env
)
=>
WSAPI
(
AsServerT
m
)
wsServer
=
WSAPI
{
wsAPIServer
=
streamData
}
where
streamData
::
(
IsGargServer
env
err
m
,
HasDispatcher
env
,
HasSettings
env
)
streamData
::
(
IsGargServer
env
err
m
,
HasDispatcher
env
Dispatcher
,
HasSettings
env
)
=>
WS
.
PendingConnection
->
m
()
streamData
pc
=
do
authSettings
<-
view
settings
d
<-
view
hasDispatcher
let
subscriptions
=
d
_s
ubscriptions
d
let
subscriptions
=
d
ispatcherS
ubscriptions
d
key
<-
getWSKey
pc
c
<-
liftBase
$
WS
.
acceptRequest
pc
let
ws
=
WSKeyConnection
(
key
,
c
)
...
...
stack.yaml
View file @
19f4848f
...
...
@@ -76,6 +76,10 @@
git
:
"
https://github.com/adinapoli/llvm-hs.git"
subdirs
:
-
"
llvm-hs-pure"
-
commit
:
f54fe61f06685c5af95ddff782e139d8d4e26186
git
:
"
https://github.com/adinapoli/nanomsg-haskell"
subdirs
:
-
.
-
commit
:
74a3296dfe1f0c4a3ade91336dcc689330e84156
git
:
"
https://github.com/adinapoli/servant-job.git"
subdirs
:
...
...
test/drivers/hspec/Main.hs
View file @
19f4848f
...
...
@@ -4,7 +4,6 @@ module Main where
import
Gargantext.Prelude
hiding
(
isInfixOf
)
import
Control.Concurrent
(
forkIO
,
killThread
)
import
Control.Monad
import
Data.Text
(
isInfixOf
)
import
Gargantext.Core.AsyncUpdates.CentralExchange
qualified
as
CE
...
...
@@ -42,6 +41,18 @@ startCoreNLPServer = do
stopCoreNLPServer
::
ProcessHandle
->
IO
()
stopCoreNLPServer
=
interruptProcessGroupOf
withNotifications
::
((
NotificationsConfig
,
ThreadId
,
D
.
Dispatcher
)
->
IO
a
)
->
IO
a
withNotifications
=
bracket
startNotifications
stopNotifications
where
startNotifications
::
IO
(
NotificationsConfig
,
ThreadId
,
D
.
Dispatcher
)
startNotifications
=
do
central_exchange
<-
forkIO
$
CE
.
gServer
nc
dispatcher
<-
D
.
newDispatcher
nc
pure
(
nc
,
central_exchange
,
dispatcher
)
stopNotifications
::
(
NotificationsConfig
,
ThreadId
,
D
.
Dispatcher
)
->
IO
()
stopNotifications
(
_nc
,
central_exchange
,
dispatcher
)
=
do
killThread
central_exchange
D
.
terminateDispatcher
dispatcher
nc
::
NotificationsConfig
nc
=
NotificationsConfig
{
_nc_central_exchange_bind
=
"tcp://*:15560"
...
...
@@ -49,18 +60,6 @@ nc = NotificationsConfig { _nc_central_exchange_bind = "tcp://*:15560"
,
_nc_dispatcher_bind
=
"tcp://*:15561"
,
_nc_dispatcher_connect
=
"tcp://localhost:15561"
}
startNotifications
::
IO
(
NotificationsConfig
,
ThreadId
,
DT
.
Dispatcher
)
startNotifications
=
do
central_exchange
<-
forkIO
$
CE
.
gServer
nc
dispatcher
<-
D
.
dispatcher
nc
pure
(
nc
,
central_exchange
,
dispatcher
)
stopNotifications
::
(
NotificationsConfig
,
ThreadId
,
DT
.
Dispatcher
)
->
IO
()
stopNotifications
(
_nc
,
central_exchange
,
dispatcher
)
=
do
killThread
central_exchange
killThread
$
DT
.
d_ce_listener
dispatcher
-- It's especially important to use Hspec for DB tests, because,
-- unlike 'tasty', 'Hspec' has explicit control over parallelism,
-- and it's important that DB tests are run according to a very
...
...
@@ -77,7 +76,7 @@ main = do
hSetBuffering
stdout
NoBuffering
-- TODO Ideally remove start/stop notifications and use
-- Test/API/Setup to initialize this in env
bracket
startNotifications
stop
Notifications
$
\
(
nc'
,
_
,
_
)
->
do
with
Notifications
$
\
(
nc'
,
_
,
_
)
->
do
bracket
startCoreNLPServer
stopCoreNLPServer
$
\
_
->
hspec
$
do
API
.
tests
nc'
ReverseProxy
.
tests
...
...
Przemyslaw Kaminski
@cgenie
mentioned in commit
5660aec0
·
Oct 08, 2024
mentioned in commit
5660aec0
mentioned in commit 5660aec07ec5a0a0a5468f440092c1a8f57a864e
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment