These are chat archives for vu3rdd/functorrent

29th
Jul 2015
Jaseem Abid
@jaseemabid
Jul 29 2015 01:56
@dfordivam Why do we use MVar for serverTAction and IORef for controlTAction ?
@vu3rdd @dfordivam I'm think asynchronous exceptions are the way to go. We have to assume that the app can get killed at any point with a pkill -9 or pkill -15.
We should protect a thread with bracket function, and use throwTo to kill it when appropriate
So, controlThreadMain = doExit =<< (mainLoop <=< doInitialization) will sort of become
controlThreadMain = bracket doInitialization doExit mainLoop
Then mainloop don't have to poll for a stop from main thread via a IORef or a MVar.
Also, it could be a simpler forever $ action rather than a recursive definition
Comments?
Jaseem Abid
@jaseemabid
Jul 29 2015 02:05
Also, I don't think we need ControlThreadStatus. What we are doing at a higher level is keeping track of the thread status with a field inside ControlThread. GHC will do that for us anyway with
data ThreadStatus = ThreadRunning
                  | ThreadFinished
                  | ThreadBlocked BlockReason
                  | ThreadDied
I cant really think of a case now where we actually need to send messages to ControlThread from main app via ControlThreadAction. We can start the control thread with all required info and kill it when we dont need it. In a real world scenario, even pausing a thread is stopping it for a really long time => kill the thread.
Jaseem Abid
@jaseemabid
Jul 29 2015 02:21
Also, we will need app level state management, to keep track of the added torrents, state they are in etc to persist torrents across restarts, and resume downloads. So incase we really need torrent status, it should be maintained externally. I think!
Jaseem Abid
@jaseemabid
Jul 29 2015 02:27
@dfordivam Can you please explain why we need the explicit yield? Cannot find an explanation for it anywhere.
Jaseem Abid
@jaseemabid
Jul 29 2015 03:22
Removing lenses and template haskell dependency. There is a bloody lot of this
Jaseem Abid
@jaseemabid
Jul 29 2015 03:27

This is really creepy. Definitions like

(&) :: a -> (a -> b) -> b
a & f = f a

make it close to impossible to read code without knowing all lens functions

Jaseem Abid
@jaseemabid
Jul 29 2015 03:36
TIL record patterns support setters. You can do this
Prelude> data Person = Person {name :: String, age :: Int}
Prelude> let jas = Person "Jaseem" 24
Prelude> let old = jas {age = 36}
Prelude> name old
"Jaseem"
Prelude> age old
36
Prelude> name jas
"Jaseem"
Prelude> age jas
24
Prelude> 
We really don't need lenses !
Jaseem Abid
@jaseemabid
Jul 29 2015 04:40
This message was deleted
Ramakrishnan Muthukrishnan
@vu3rdd
Jul 29 2015 05:11
@jaseemabid yes, agree on the async thread and brackets.
Jaseem Abid
@jaseemabid
Jul 29 2015 05:11
I just managed to get it compile warning free!
Ramakrishnan Muthukrishnan
@vu3rdd
Jul 29 2015 05:11
You folks are approaching it from the top-down, I am approaching it from the other side.
Jaseem Abid
@jaseemabid
Jul 29 2015 05:12
The diff is large, but individual pieces are understandable. Quite happy with the result
Simplified the code a lot.
I'm approaching from this side because you are from the other ;)
This message was deleted
Divam
@dfordivam
Jul 29 2015 05:13
I am not sure about the async part...
the lenses removal is ok
Jaseem Abid
@jaseemabid
Jul 29 2015 05:14
Hey you are back! nice to have both of you together :)
The average diff will look like this
-          a <- readMVar (st1^.activeTorrents)
-          putMVar (st1^.activeTorrents) (t:a)
+          a <- readMVar (activeTorrents st1)
+          putMVar (activeTorrents st1) (t : a)
Divam
@dfordivam
Jul 29 2015 05:15
There has to be handling of async exceptions but I am not sure whether we should use it to do regular thread management
Jaseem Abid
@jaseemabid
Jul 29 2015 05:15
I have a feeling that they can be merged.
In short, make the individual threads do their job in a thread safe way. With proper init, action and cleanup steps. Wrap in a bracket. Now you or someone else can kill it anytime
@dfordivam I asked a bunch of questions above. Mostly stuff I'm not very sure about. Please answer
Divam
@dfordivam
Jul 29 2015 05:18
We need a global state for torrents, and we need to update this using the data from controlthread, so ControlThreadStatus is a placeholder for this communication
Jaseem Abid
@jaseemabid
Jul 29 2015 05:19
So its a way for the control thread to send data to the main state?
Divam
@dfordivam
Jul 29 2015 05:20
Yes
Jaseem Abid
@jaseemabid
Jul 29 2015 05:20
Hmm.. I need to think through.
  1. @dfordivam Why do we use MVar for serverTAction and IORef for controlTAction ?
  2. Why yield ?
Divam
@dfordivam
Jul 29 2015 05:22
  1. If I want the thread to wait for some action/input then I have used MVar
  1. Give the other threads control, so that they can finish cleanup.
  1. Give the other threads control, so that they can finish cleanup.
what !!
Jaseem Abid
@jaseemabid
Jul 29 2015 05:25
Why not MVar everywhere? IORef I believe is not thread safe.
@dfordivam @vu3rdd Code with and without lenses :)
-            let ct1 = trackerResponses %~ (trackerResp : ) $ ct
-                ct2 = peerList %~ ((peers trackerResp) ++) $ ct1
-            in return ct2
+            let newTrackerResponses = trackerResp : trackerResponses ct
+                newPeerList = peerList ct ++ peers trackerResp
+            in return ct {trackerResponses = newTrackerResponses,
+                          peerList = newPeerList}
Divam
@dfordivam
Jul 29 2015 05:27
The real candidates for MVar is actually TransferStats in PeerThread
Rest everywhere else we can actually use IORef
Jaseem Abid
@jaseemabid
Jul 29 2015 05:28
Is there a reason to use IORef over MVar? Can we use just one thing everywhere?
Divam
@dfordivam
Jul 29 2015 05:29
MVar has a property of being empty.. This can be utilised at various places
So we can actually use MVar everywhere.. but why don't use IORef?
Jaseem Abid
@jaseemabid
Jul 29 2015 05:31
I was just looking for consistency and trying to understand why. Not a counter argument.
Also yield ?
I think we will eventually find the right fit for the job. Also, Haskell refactor is such a pleasure :)
Divam
@dfordivam
Jul 29 2015 05:32
For yeild : Give the other threads control, so that they can finish cleanup.
Jaseem Abid
@jaseemabid
Jul 29 2015 05:33
Do we have to be explicit? I couldnt find relevant documentation
Divam
@dfordivam
Jul 29 2015 05:34
I am not sure.. Since this function is provided I thought of using it..
Jaseem Abid
@jaseemabid
Jul 29 2015 05:36
Okay. I think we'll figure out.
Jaseem Abid
@jaseemabid
Jul 29 2015 05:48
@dfordivam Please have a careful look at bangalore-haskell-user-group/functorrent#39
Comment on the PR or here if you find any issues.
Jaseem Abid
@jaseemabid
Jul 29 2015 06:18
The travis buils are failing. Runs fine locally :(
Jaseem Abid
@jaseemabid
Jul 29 2015 06:25
@vu3rdd Can you check if you can build locally? GHC 7.8 is not compiling it seems. Works fine for me with 7.10
import Data.Functor ((<$>)) is not required for me somehow
Failing on travis
Jaseem Abid
@jaseemabid
Jul 29 2015 06:33
I need a break. Leave messages here. Will be back in a while
Jaseem Abid
@jaseemabid
Jul 29 2015 07:55
@vu3rdd there?
Divam
@dfordivam
Jul 29 2015 14:06
@jaseemabid you may merge this after adding <$> import
Jaseem Abid
@jaseemabid
Jul 29 2015 17:30
@dfordivam I'm wondering how its working fine for me locally
GHC/base changes b/w 7.8 and 7.10?
Jaseem Abid
@jaseemabid
Jul 29 2015 17:53
I have it magically imported in peer.hs
dont know ow
Jaseem Abid
@jaseemabid
Jul 29 2015 18:02
See this!
ghci src/FuncTorrent/Peer.hs 
GHCi, version 7.10.1.20150715: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling FuncTorrent.Peer ( src/FuncTorrent/Peer.hs, interpreted )
Ok, modules loaded: FuncTorrent.Peer.
*FuncTorrent.Peer> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
*FuncTorrent.Peer> 
I have <$>
Jaseem Abid
@jaseemabid
Jul 29 2015 18:27
it's in the Prelude in 7.10 as part of the Applicative-Monad reorganization
[23:56] <arkeet> @hoogle <$>
[23:56] <lambdabot> Data.Functor (<$>) :: Functor f => (a -> b) -> f a -> f b
[23:56] <lambdabot> Control.Applicative (<$>) :: Functor f => (a -> b) -> f a -> f b
Jaseem Abid
@jaseemabid
Jul 29 2015 18:37
@dfordivam Fixed here jaseemabid/functorrent@1e83942
Let the build complete
Jaseem Abid
@jaseemabid
Jul 29 2015 18:54
And 2 more. I have to push to travis to test 7.8 :(
That worked, Merging in