<commit_before>_           = require '../vendor/lodash'
path        = require 'path'
http        = require 'http'
express     = require 'express'
socketio    = require 'socket.io'
Promise     = require 'bluebird'
chalk       = require 'chalk'
timm        = require 'timm'
treeLines   = require '../gral/treeLines'
k           = require '../gral/constants'

DEFAULT_CONFIG = 
  port: 8090
  throttle: 200
  authenticate: null
LOG_SRC = 'storyboard'
_ioStandalone = null
_ioServerAdaptor = null

#-------------------------------------------------
# ## WebSocket I/O
#-------------------------------------------------
_socketInit = (config) ->
  return if _ioStandalone   # only one server
  {port, mainStory: story} = config

  # Launch stand-alone log server
  expressApp = express()
  expressApp.use express.static path.join(__dirname, '../../serverLogsApp')
  httpServer = http.createServer expressApp
  _ioStandalone = socketio(httpServer).of k.WS_NAMESPACE
  _ioStandalone.on 'connection', (socket) -> _socketOnConnection socket, config
  httpServer.listen port
  story.info LOG_SRC, "Server logs available on port #{chalk.cyan port}"

  # If a main application server is also provided, 
  # launch another log server on the same application port
  if config.socketServer
    _ioServerAdaptor = config.socketServer.of k.WS_NAMESPACE
  else if config.httpServer
    _ioServerAdaptor = socketio(config.httpServer).of k.WS_NAMESPACE
  if _ioServerAdaptor
    _ioServerAdaptor.on 'connection', (socket) -> _socketOnConnection socket, config
    try
      port2 = _ioServerAdaptor.server.httpServer.address().port
      story.info LOG_SRC, "Server logs also available through main HTTP server on port #{chalk.cyan port2}"
    catch
      story.info LOG_SRC, "Server logs also available through main HTTP server (#{chalk.red 'port could not be determined'})"
  return

_socketOnConnection = (socket, config) ->
  socket.sbAuthenticated = not config.authenticate?
  socket.sbConfig = config
  if socket.sbAuthenticated
    socket.join 'AUTHENTICATED'
  else
    _socketTxMsg socket, {type: 'LOGIN_REQUIRED'}
  socket.on 'MSG', (msg) -> _socketRxMsg socket, msg

_socketRxMsg = (socket, msg) ->
  {type, data} = msg
  {mainStory: story, hub} = socket.sbConfig
  switch type
    when 'LOGIN_REQUEST'
      {authenticate} = socket.sbConfig
      {login} = credentials = data
      Promise.resolve (socket.sbAuthenticated) \
        or (not authenticate?) or authenticate(credentials)
      .then (fAuthValid) ->
        rsp = {type: 'LOGIN_RESPONSE'}
        if fAuthValid
          rsp.result = 'SUCCESS'
          story.info LOG_SRC, "User '#{login}' authenticated successfully"
          socket.sbAuthenticated = true
          socket.join 'AUTHENTICATED'
          rsp.data = 
            login: login
            bufferedRecords: _getBufferedRecords hub
        else
          rsp.result = 'ERROR'
          story.warn LOG_SRC, "User '#{login}' authentication failed"
        _socketTxMsg socket, rsp
    ## when 'BUFFERED_RECORDS_REQUEST'
    ##   rsp = {type: 'BUFFERED_RECORDS_RESPONSE'}
    ##   if socket.sbAuthenticated
    ##     rsp.result = 'SUCCESS'
    ##     rsp.data = hub.getBufferedRecords()
    ##   else
    ##     rsp.result = 'ERROR'
    ##     rsp.error = 'AUTH_REQUIRED'
    ##   _socketTxMsg socket, rsp
    else
      story.warn LOG_SRC, "Unknown message type '#{type}'"
  return

_socketTxMsg = (socket, msg) -> socket.emit 'MSG', msg

_socketBroadcast = ->
  msg = {type: 'RECORDS', data: _broadcastBuf}<commit_msg>Solve race condition in server listener (injecting logs in the circuit)<commit_after>_           = require '../vendor/lodash'
path        = require 'path'
http        = require 'http'
express     = require 'express'
socketio    = require 'socket.io'
Promise     = require 'bluebird'
chalk       = require 'chalk'
timm        = require 'timm'
treeLines   = require '../gral/treeLines'
k           = require '../gral/constants'

DEFAULT_CONFIG = 
  port: 8090
  throttle: 200
  authenticate: null
LOG_SRC = 'storyboard'
_ioStandalone = null
_ioServerAdaptor = null

#-------------------------------------------------
# ## WebSocket I/O
#-------------------------------------------------
_socketInit = (config) ->
  return if _ioStandalone   # only one server
  {port, mainStory} = config

  # Launch stand-alone log server
  expressApp = express()
  expressApp.use express.static path.join(__dirname, '../../serverLogsApp')
  httpServer = http.createServer expressApp
  _ioStandalone = socketio(httpServer).of k.WS_NAMESPACE
  _ioStandalone.on 'connection', (socket) -> _socketOnConnection socket, config
  httpServer.listen port
  mainStory.info LOG_SRC, "Server logs available on port #{chalk.cyan port}"

  # If a main application server is also provided, 
  # launch another log server on the same application port
  if config.socketServer
    _ioServerAdaptor = config.socketServer.of k.WS_NAMESPACE
  else if config.httpServer
    _ioServerAdaptor = socketio(config.httpServer).of k.WS_NAMESPACE
  if _ioServerAdaptor
    _ioServerAdaptor.on 'connection', (socket) -> _socketOnConnection socket, config
    try
      port2 = _ioServerAdaptor.server.httpServer.address().port
      mainStory.info LOG_SRC, "Server logs also available through main HTTP server on port #{chalk.cyan port2}"
    catch
      mainStory.info LOG_SRC, "Server logs also available through main HTTP server (#{chalk.red 'port could not be determined'})"
  return

_socketOnConnection = (socket, config) ->
  socket.sbAuthenticated = not config.authenticate?
  socket.sbConfig = config
  if socket.sbAuthenticated
    socket.join 'AUTHENTICATED'
  else
    _socketTxMsg socket, {type: 'LOGIN_REQUIRED'}
  socket.on 'MSG', (msg) -> _socketRxMsg socket, msg

_socketRxMsg = (socket, msg) ->
  {type, data} = msg
  {mainStory, hub} = socket.sbConfig
  switch type
    when 'LOGIN_REQUEST'
      {authenticate} = socket.sbConfig
      {login} = credentials = data
      Promise.resolve (socket.sbAuthenticated) \
        or (not authenticate?) or authenticate(credentials)
      .then (fAuthValid) ->
        rsp = {type: 'LOGIN_RESPONSE'}
        if fAuthValid
          rsp.result = 'SUCCESS'
          process.nextTick -> mainStory.info LOG_SRC, "User '#{login}' authenticated successfully"
          socket.sbAuthenticated = true
          socket.join 'AUTHENTICATED'
          rsp.data = 
            login: login
            bufferedRecords: _getBufferedRecords hub
        else
          rsp.result = 'ERROR'
          process.nextTick -> mainStory.warn LOG_SRC, "User '#{login}' authentication failed"
        _socketTxMsg socket, rsp
    ## when 'BUFFERED_RECORDS_REQUEST'
    ##   rsp = {type: 'BUFFERED_RECORDS_RESPONSE'}
    ##   if socket.sbAuthenticated
    ##     rsp.result = 'SUCCESS'
    ##     rsp.data = hub.getBufferedRecords()
    ##   else
    ##     rsp.result = 'ERROR'
    ##     rsp.error = 'AUTH_REQUIRED'
    ##   _socketTxMsg socket, rsp
    else
      process.nextTick -> mainStory.warn LOG_SRC, "Unknown message type '#{type}'"
  return

_socketTxMsg = (socket, msg) -> socket.emit 'MSG', msg

_socketBroadcast = ->
  msg = {type: 'RECORDS', data: _broadcastBuf}
{'fraction_non_alphanumeric': 0.12729039422543031, 'fraction_numerical': 0.002498611882287618, 'mean_word_length': 2.7624020887728458, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1052217', 'n_tokens_mistral': 2214, 'n_tokens_neox': 2182, 'n_words': 582}