There are lot of log statements in some important method, they are used to log the progress and some important information.
val result = user.login()
if(result) {
logger.info("User has logged in successful: " + user.id)
val questions = user.queryQuestions()
logger.info("User has " + questions.size + " questions")
val latestQuestion = questions.headOption
logger.info("The latest question is: " + latestQuestion)
...
} else {
logger.info("User has logged failed: " + user.id)
}
Suppose all the log information are very important, they need to be logged and audit. But the code looks like Java rather than Scala.
How can we improve it so it looks more functional and less side-effect?
Related
I'm trying to simulate routes from the retailer to the customer in the US in Anylogic and wanted to know what routes could be done by rail. But, if a rail route does not exist I get an error, and the simulation stops. I want the simulation to run and if the route does not exist, it saves in a variable (like a boolean variable, if the route exists it's true and if not is false). Thanks for the help!
You should have a map object that has the road type set to rail and one that has the road type set to rail
Then with some simple code, you can check if there is a rail that exists and if not do something else.
try {
GISRoute route = map.getRoute(fromLatitude, fromLongitude, toLatitude,
toLatitude);
} catch (Exception e) {
traceln("Error - no route found - from " + fromLatitude) + ", " +
fromLongitude + " to " + toLatitude + ", " + toLongitude);
traceln("Exception " + e);
// Maybe look for a road route?
}
as a beginner I am trying to test new Unity Packages - Unity Lobby and Unity Relay to make multiplayer card game. Quick joining lobby and creating a lobby works fine but I have encountered a problem with joining lobby using Join Code. Here's the code:
public async void JoinByCode() {
string lobbyCode = InputField.text;
Debug.Log(lobbyCode);
Debug.Log("Searching for lobby with code " + lobbyCode + "...");
// UpdateState ?.Invoke("Searching for lobby with code " + lobbyCode + "...");
try {
JoinLobbyByCodeOptions options = new JoinLobbyByCodeOptions();
Lobby lobby = await Lobbies.Instance.JoinLobbyByCodeAsync(lobbyCode, options); //<--- results in error 400 - Bad Request
Debug.Log(lobby);
Debug.Log("Joined lobby: " + lobby.Id);
Debug.Log("Players in lobby: " + lobby.Players.Count);
//RelayCode
string joinCode = lobby.Data["joinCode"].Value;
Debug.Log("Kod dostępu: " + joinCode);
JoinAllocation allocation = await Relay.Instance.JoinAllocationAsync(joinCode);
//obiekt joindata
_joinData = new RelayJoinData {
Key = allocation.Key,
Port = (ushort) allocation.RelayServer.Port,
AllocationID = allocation.AllocationId,
AllocationIDBytes = allocation.AllocationIdBytes,
ConnectionData = allocation.ConnectionData,
HostConnectionData = allocation.HostConnectionData,
IPv4Address = allocation.RelayServer.IpV4
};
_joinData.JoinCode = await Relay.Instance.GetJoinCodeAsync(allocation.AllocationId);
NetworkManager.Singleton.GetComponent<UnityTransport>().SetClientRelayData(
_joinData.IPv4Address,
_joinData.Port,
_joinData.AllocationIDBytes,
_joinData.Key,
_joinData.ConnectionData,
_joinData.HostConnectionData
);
NetworkManager.Singleton.StartClient();
Debug.Log("Found lobby, code: " + joinCode);
UpdateState?.Invoke("Joining lobby, code: " + joinCode + ", players in lobby: " + lobby.Players.Count);
MatchFound?.Invoke();
} catch (LobbyServiceException e) {
Debug.Log("There's a problem finding lobby, try again. " + e);
}
}
In general: Join Code is passed from InputField, then to JoinLobbyByCodeAsync, then send player data to server. The problem is with variable lobby - when I am trying to test JoinByCode, it results with error:
There's a problem finding lobby, try again. Unity.Services.Lobbies.LobbyServiceException: request failed validation ---> Unity.Services.Lobbies.Http.HttpException`1[Unity.Services.Lobbies.Models.ErrorStatus]: HTTP/1.1 400 Bad Request
and I have no idea how to solve this problem. Yes, I was using Unity Documentation for Lobby and trying to find any info about error 400 in Lobby. I will be really grateful if someone could help me with this problem. Cheers!
I had a similar problem, in my case the input contained an extra character. Make sure that there are only 6 characters in your variable "lobbyCode" by checking it with lobbyCode.Length. Also make sure that you have activated the Lobby and Relay service in the dashboard.
My post to this problem:
https://forum.unity.com/threads/problem-joining-a-private-lobby-through-lobbycode-joinlobbybycodeasync.1287908/#post-8171102
I'm writing a web service and am often sending messages over HTTPS.
val response = sendJson(JsonUtil.getTextMessageJson("Sorry I don't understand what day you want. You can say " + "things like \"tomorrow\" or \"next Friday\""))
I could follow this call with onComplete {} and handle the resulting Success or Failure but since I do this so often I have written a simple function in a helper class:
def logSendResult(response: Future[WSResponse])(implicit userId: String): Unit = {
response onComplete {
case Success(res) => Logger.info("Message to " + userId + " sent successfully with " +
"response code: " + res.status)
case Failure(exception) => Logger.info("Message to " + userId + " failed with " +
"exception: " + exception.getMessage)
}
}
Which I then call with:
LogUtils.logSendResult(response)
This is working fine but I was wondering if there is a better way?
I believe you have a cross cutting concerns. If not handled properly might cause problem: https://en.wikipedia.org/wiki/Cross-cutting_concern
AOP (aspect oriented programming) can fix 'cross cutting concerns'.
Here is a sample AOP program using AspectJ library in scala.
This sample aspect will print Method, its input and result detail, when a method is entered annotated with the #Loggable annotation and finished execution.
https://github.com/knoldus/CrossCuttingConcern_Scala/blob/master/src/main/scala/com/knoldus/aspect/Aspect.scala
Hope this help. Best of luck!
HTTP Filters
This sounds like a good application of a Filter https://www.playframework.com/documentation/2.5.x/ScalaHttpFilters
In the example they even show ho to Build a logging Filter.
I'm new to scala and extremely new to scalaz. Through a different stackoverflow answer and some handholding, I was able to use scalaz.stream to implement a Process that would continuously fetch twitter API results. Now i'd like to do the same thing for the Cassandra DB where the twitter handles are stored.
The code for fetching the twitter results is here:
def urls: Seq[(Handle,URL)] = {
Await.result(
getAll(connection).map { List =>
List.map(twitterToGet =>
(twitterToGet.handle, urlBoilerPlate + twitterToGet.handle + parameters + twitterToGet.sinceID)
)
},
5 seconds)
}
val fetchUrl = channel.lift[Task, (Handle, URL), Fetched] {
url => Task.delay {
val finalResult = callTwitter(url)
if (finalResult.tweets.nonEmpty) {
connection.updateTwitter(finalResult)
} else {
println("\n" + finalResult.handle + " does not have new tweets")
}
s"\ntwitter Fetch & database update completed"
}
}
val P = Process
val process =
(time.awakeEvery(3.second) zipWith P.emitAll(urls))((b, url) => url).
through(fetchUrl)
val fetched = process.runLog.run
fetched.foreach(println)
What I'm planning to do is use
def urls: Seq[(Handle,URL)] = {
to continuously fetch Cassandra results (with an awakeEvery) and send them off to an actor to run the above twitter fetching code.
My question is, what is the best way to implement this with scalaz.stream? Note that i'd like it to get ALL the database results, then have a delay before getting ALL the database results again. Should i use the same architecture as the twitter fetching code above? If so, how would I create a channel.lift that doesn't require input? Is there a better way in scalaz.stream?
Thanks in advance
Got this working today. The cleanest way to do it would be to emit the database results as a stream and attach a sink to the end of the stream to do the twitter processing. What I actually have is a bit more complex as it retrieves the database results continuously and sends them off to an actor for the twitter processing. The style of retrieving the results follows my original code from my question:
val connection = new simpleClient(conf.getString("cassandra.node"))
implicit val threadPool = new ScheduledThreadPoolExecutor(4)
val system = ActorSystem("mySystem")
val twitterFetch = system.actorOf(Props[TwitterFetch], "twitterFetch")
def myEffect = channel.lift[Task, simpleClient, String]{
connection: simpleClient => Task.delay{
val results = Await.result(
getAll(connection).map { List =>
List.map(twitterToGet =>
(twitterToGet.handle, urlBoilerPlate + twitterToGet.handle + parameters + twitterToGet.sinceID)
)
},
5 seconds)
println("Query Successful, results= " +results +" at " + format.print(System.currentTimeMillis()))
twitterFetch ! fetched(connection, results)
s"database fetch completed"
}
}
val P = Process
val process =
(time.awakeEvery(3.second).flatMap(_ => P.emit(connection).
through(myEffect)))
val fetching = process.runLog.run
fetching.foreach(println)
Some notes:
I had asked about using channel.lift without input, but it became clear that the input should be the cassandra connection.
The line
val process =
(time.awakeEvery(3.second).flatMap(_ => P.emit(connection).
through(myEffect)))
Changed from zipWith to flatMap because I wanted to retrieve the results continuously instead of once.
I'm trying to use Smack to transfer a file between two PCs connected on the same XMPP server, but I get a weird error.
To summarize, the destination PC has a FileTransferListener registered, like so:
ftm.addFileTransferListener(new FileTransferListener() {
#Override
public void fileTransferRequest(FileTransferRequest request) {
System.out.println("Request received");
if (true) // Check to see if the request should be accepted
{
// Accept it
System.out.println("Entering FTListener because of FTRequest");
IncomingFileTransfer transfer = request.accept();
String id = request.getDescription();
String path = savePoint + System.getProperty("file.separator") + request.getFileName();
try
{
System.out.println("Receiving...");
transfer.recieveFile(new File(path));
// Information put in HashMap for later retrieval
System.out.println("IM - putting in path (" + id + "," + path + ")");
paths.put(id, path);
} catch (XMPPException e) {
logger.error("Error getting the VM file: " + e.getMessage());
}
}
else
{
// Reject it
request.reject();
logger.info("VM file transfer rejected");
}
}
});
The source PC uses an OutgoingFileTransfer like so:
try
{
String nick = destHost + "#" + this.conn.getServer() + "/Smack";
//destHost = destination host name, conn = XMPP connection
System.out.println("OFT to " + nick);
OutgoingFileTransfer.setResponseTimeout(10000);
OutgoingFileTransfer oft = ftm.createOutgoingFileTransfer(nick);
oft.sendFile(f, name); //f = file to send, name = a message
while (!oft.isDone())
{
if (oft.getStatus().equals(Status.error))
{
System.out.println("ERROR!!! " + oft.getError());
oft.cancel();
return false;
}
System.out.println(oft.getStatus());
System.out.println(oft.getProgress());
System.out.println("5 sec sleep");
Thread.sleep(5000);
}
if (oft.getStatus().equals(Status.complete))
{
System.out.println("Transfer done");
return true;
}
if (oft.getStatus().equals(Status.error))
System.out.println("Transfer failed: " + oft.getError());
return false;
} catch (XMPPException e) {
System.out.println("Error sending VM image file with the FTM : " + e.getMessage());
return false;
} catch (InterruptedException e) {
System.err.println("Error sleeping during OFT : " + e.getMessage());
return false;
}
When I try to send a file, the outgoing file transfer begins, and the destination PC receives the request, but the source PC cannot go further then the transfer negotiation.
This is seen in the source PC output...
Initial
0.0
2 sec sleep
Negotiating Transfer
0.0
2 sec sleep
Negotiating Stream
0.0
2 sec sleep
Transfer failed: null
I'm really annoyed because I don't even get a proper error message, so I don't really know what went wrong.
Has this ever happened to anyone else?
Looks like you are running into a known issue in Smack that will hopefully be fixed in the next release.
Update: This is now fixed and will be in version 3.2.1.
XMPP bytestreams are well specified, but are a rather complex topic, because there is more than one way to establish such a stream.
Your code looks right on a quick review. Now the next step would be to analyze the XMPP stanzas send between both clients and the server. This should give you a hint about the error cause. Also make sure to use smack 3.2.0 which has IBB support, which should increase the chance of a successful file transfer via XMPP.