I am using Haskell for the redis server
I am trying to debug, but it doesn’t work
@dawkrish Could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.
I’ll try to run your code and get back to you tomorrow.
Okay sure, just wait a minute
I dont know how I can
because it already has a remote set
@dawkrish Printing to stderr
should work:
import System.IO (stderr, hPutStrLn)
main :: IO ()
main = do
let port = "6379"
hPutStrLn stderr "Logs from your program will appear here"
hPutStrLn stderr $ "Redis server listening on port " ++ port
TCP.serve TCP.HostAny port $ \(socket, address) -> do
hPutStrLn stderr $ "Client connected: " ++ show address
loop socket
hPutStrLn stderr $ "Client disconnected: " ++ show address
Okay thanks ! But why is not printing to stdout working? Is it due to Haskell or is it same for every language ??!
TBH, I’m not quite sure why stdout is not working for Haskell, because it works for other languages.
I need to investigate a bit and get back to you later.
Thanks a lot ! I will use stderr till then. You have saved me big time
@dawkrish Turns out the issue is due to buffering. You can manually flush stdout like this:
import System.IO (hFlush, stdout)
main :: IO ()
main = do
let port = "6379"
putStrLn $ "Redis server listening on port " ++ port
hFlush stdout
I don’t understand this but I guess you flushing means clearing the previous stdout ?
Here’s an explanation from ChatGPT:
In many programming languages, stdout output is buffered. This buffering can delay the appearance of printed content until:
• The buffer is full
• The program ends
• A newline character (\n) is encountered (in some cases)When you flush stdout, you ensure that everything written to the output buffer is immediately sent to the terminal.
Okie ! Thanks .
I hope the Haskell issue fixes
@andy1li can you raise an issue to get this fix because this way of doing is a bit irritating
This is my code right now
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import qualified Network.Simple.TCP as TCP
import qualified Data.ByteString as BS
import System.IO (stderr, hPutStrLn, hPrint)
import qualified RESP
main :: IO ()
main = do
let port = "6379"
putStrLn $ "Redis server listening on port " ++ port
TCP.serve TCP.HostAny port $ \(socket, address) -> do
printToStdOut $ "Client connected: " ++ show address
loop socket
printToStdOut $ "Client disconnected: " ++ show address
loop :: TCP.Socket -> IO()
loop sock = do
msg <- TCP.recv sock 1024
case msg of
Nothing -> printToStdOut "Client has exited!"
(Just bs) -> do
handleCommand sock bs
loop sock
handleCommand :: TCP.Socket -> BS.ByteString -> IO()
handleCommand sock cmd
| cmd == "PING\n" = TCP.send sock "+PONG\r\n"
| otherwise = do
printToStdOut cmd
TCP.send sock cmd
printToStdOut :: Show a => a -> IO()
printToStdOut = hPrint stderr
can you raise an issue to get this fix because this way of doing is a bit irritating
@dawkrish Could you clarify a bit more on what you’d like to get fixed?
using “putStrLn” (that goes to stdout) to use in debug mode
@dawkrish You can use hSetBuffering
to disable buffering like this:
+ import System.IO (stderr, stdout, hSetBuffering, BufferMode(NoBuffering))
main :: IO ()
main = do
+ hSetBuffering stdout NoBuffering
+ hSetBuffering stderr NoBuffering
let port = "6379"
putStrLn $ "Redis server listening on port " ++ port
TCP.serve TCP.HostAny port $ \(socket, address) -> do
printToStdOut $ "Client connected: " ++ show address
loop socket
printToStdOut $ "Client disconnected: " ++ show address
Hm, for now I am just using my custom function which is there in my above code snippet “printToStdout” . I don’t understand buffering so I am avoiding that solution
By the way for other languages like python, the simple “print”, for C++, the “cout” are working fine ?