-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathUser.fs
More file actions
104 lines (79 loc) · 3.26 KB
/
Copy pathUser.fs
File metadata and controls
104 lines (79 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
module User
open MessageTypes
open Requests
open System
open Akka.FSharp
open Akka.Actor
open Suave.WebSocket
open Suave.Sockets
open Suave.Sockets.Control
open Suave
open System.Net.WebSockets
open System.Threading
open System.Text
open Newtonsoft.Json
let fromJson<'a> json =
JsonConvert.DeserializeObject(json, typeof<'a>) :?> 'a
let rand = Random()
let twitterUser (username: string) (numUsers: int) (numSubscribers: int) (numTweets: int) (mailbox : Actor<UserMsg>) =
let ws = new ClientWebSocket()
let wsUri = Uri("ws://localhost:8080/tweets/stream")
let openTweetSocket =
async{
do! Async.AwaitTask (ws.ConnectAsync(wsUri, CancellationToken.None))
}
let postTweets =
async{
for i in 0..numTweets-1 do
let mutable tweetContent = "Tweet content here!"
// add random hashtag to tweet 11% of the time
if rand.NextDouble() <= 0.11 then
tweetContent <- tweetContent + " #tag" + rand.Next(10).ToString()
// add random mention to tweet 49% of the time
if rand.NextDouble() <= 0.49 then
tweetContent <- tweetContent + " @user" + rand.Next(numUsers).ToString()
let json = JsonConvert.SerializeObject(TweetMsg(tweetContent, username))
makeRequest "/postTweet" "POST" json |> ignore
}
let viewTweet (id: int) (tweet: string) (user: string) =
// retweet viewed tweet 13% of the time
if rand.NextDouble() <= 0.13 then
let json = JsonConvert.SerializeObject(ReTweetMsg(id, username))
makeRequest "/reTweet" "POST" json |> ignore
let login =
let json = JsonConvert.SerializeObject(UsernameMsg(username))
// makeRequest "/login" "PUT" json |> ignore
openTweetSocket |> Async.RunSynchronously
let byteData =
json
|> System.Text.Encoding.ASCII.GetBytes
|> ByteSegment
ws.SendAsync (byteData, WebSocketMessageType.Text, true, CancellationToken.None)
let toggleDisconnection =
// 25% chance to toggle period of disconnectivity
async{
if rand.NextDouble() <= 0.1 then
let json = JsonConvert.SerializeObject(UsernameMsg(username))
makeRequest "/logout" "PUT" json |> ignore
do! Async.Sleep (rand.Next(2500)) // disconnect for up to 2.5 seconds
makeRequest "/login" "PUT" json |> ignore
}
login |> ignore
postTweets |> Async.Start
let rec loop () =
Akka.Dispatch.ActorTaskScheduler.RunTask(fun() ->
toggleDisconnection |> Async.StartAsTask :> Tasks.Task)
actor {
let mutable contents = ""
while ws.State = WebSocketState.Open do
let buff = ArraySegment<byte>(Array.zeroCreate 1028)
let result = ws.ReceiveAsync(buff, CancellationToken.None).Result
contents <- Encoding.UTF8.GetString(buff.Array, 0, result.Count)
try
let data = contents |> fromJson<ReceiveTweetMsg>
viewTweet data.id data.tweet data.user
with
|_->()
return! loop()
}
loop()