applying future where can be exception comes - multithreading

this code works fine but i want to manage threads, by Future.
sendSMS method takes normally 3 to 5 seconds to execute, i want to applying future and applied at one place but want to know is it enough or not?
val c = for {
t <- Future { doSendSms("+9178787878787","i scare with threads") }
} yield t
c.map { res =>
res match {
case e: Error => {
Ok(write(Map("result" -> "error")))
}
case Success() => {
Ok(write(Map("result" -> "success")))
}
def doSendSms(recipient: String, body: String): SentSmsResult = {
try {
sendSMS(recipient, body)
Success()
} catch {
case twilioEx: TwilioRestException =>
return Error(twilioEx.toString)
case e: Exception =>
return Error(e.toString)
}
}
def sendSMS(smsTo: String, body: String) = {
val params = Map("To" -> smsTo, "From" -> twilioNumber, "Body" -> body)
val messageFactory = client.getAccount.getSmsFactory
messageFactory.create(params)
}// sending sms from twilio, this method takes 3 to 5 seconds to execute
if not how to manage Future in this code

I would use recover:
val c = for {
t <- doSendSms("+9178787878787","i scare with threads")
} yield t
def doSendSms(recipient: String, body: String): Future[SentSmsResult] =
Future {
sendSMS(recipient, body)
}
.recover {
case twilioEx: TwilioRestException => Error(twilioEx.toString)
case e: Exception => Error(e.toString)
}
}
recover will catch exceptions thrown in the future execution allowing you to return a new result wrapped in a Future, as the documentation states:
The recover combinator creates a new future which holds the same result as the original future if it completed successfully. If it did not then the partial function argument is applied to the Throwable which failed the original future.

Related

TS decorator to wrap function definition in try catch

Is it possible to use TS decorator to wrap a function definition into a try-catch block. I don't want to use try-catch in every function so I was thinking maybe decorators can help.
For example
function examleFn(errorWrapper: any) {
try{
// some code
} catch (err) {
errorWrapper(err)
}
}
Something like this can be done in a decorator so that it can be used for other functions too.
No, you cannot decorate functions.
TypeScript's implementation of decorators can only apply to classes, class methods, class accessors, class properties, or class method parameters. The relevant proposal for JavaScript decorators (at Stage 3 of the TC39 Process as of today, 2022-07-21) also does not allow for decorating functions.
Function decorators are mentioned as possible extensions to the decorator proposal, but are not currently part of any proposal for either TypeScript or JavaScript.
You can, of course, call a decorator-like function on another function, but this is just a higher-order function and not a decorator per se, and it won't affect the original function declaration:
const makeErrorWrapper = <T,>(errorHandler: (err: any) => T) =>
<A extends any[], R>(fn: (...a: A) => R) =>
(...a: A): R | T => {
try {
return fn(...a);
} catch (err) {
return errorHandler(err);
}
};
The makeErrorWrapper function takes an error handler and returns a new function that wraps other functions with that error handler:
const errToUndefined = makeErrorWrapper(err => undefined);
So now errToUndefined is a function wrapper. Let's say we have the following function which throws errors:
function foo(x: string) {
if (x.length > 3) throw new Error("THAT STRING IS TOO LONG");
return x.length;
}
// function foo(x: string): number
If you call it directly, you can get runtime errors:
console.log(foo("abc")); // 3
console.log(foo("abcde")); // 💥 THAT STRING IS TOO LONG
Instead you can wrap it:
const wrappedFoo = errToUndefined(foo);
// const wrappedFoo: (x: string) => number | undefined
Now wrappedFoo is a new function that behaves like foo and takes the same parameter list as foo, but returns number | undefined instead of just number:
console.log(wrappedFoo("abc")) // 3
console.log(wrappedFoo("abcde")) // undefined
Playground link to code
maybe this can help you, it took me a long time to do it, but here it is
function Execpetion (methodName: string) {
return (target: any, nameMethod: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value
descriptor.value = async function (...args: any[]) {
try {
const executionMethod = await originalMethod.apply(this, args)
return executionMethod
} catch (error) {
return errorWrapper(error as Error)
}
}
}
}
in your class
class TestController {
#Execpetion('TestController')
public async handler (teste: any) {
return {
statusCode: 200,
data: 'nothing'
}
}
}
with the parent function, you can modify and add to receive the errorPersonalized and instantiated type parameter... and on the return put it

Get return value from thread, is this Kotlin code thread safe?

I would like to run some treads, wait till all of them are finished and get the results.
Possible way to do that would be in the code below. Is it thread safe though?
import kotlin.concurrent.thread
sealed class Errorneous<R>
data class Success<R>(val result: R) : Errorneous<R>()
data class Fail<R>(val error: Exception) : Errorneous<R>()
fun <R> thread_with_result(fn: () -> R): (() -> Errorneous<R>) {
var r: Errorneous<R>? = null
val t = thread {
r = try { Success(fn()) } catch (e: Exception) { Fail(e) }
}
return {
t.join()
r!!
}
}
fun main() {
val tasks = listOf({ 2 * 2 }, { 3 * 3 })
val results = tasks
.map{ thread_with_result(it) }
.map{ it() }
println(results)
}
P.S.
Are there better built-in tools in Kotlin to do that? Like process 10000 tasks with pool of 10 threads?
It should be threads, not coroutines, as it will be used with legacy code and I don't know if it works well with coroutines.
Seems like Java has Executors that doing exactly that
fun <R> execute_in_parallel(tasks: List<() -> R>, threads: Int): List<Errorneous<R>> {
val executor = Executors.newFixedThreadPool(threads)
val fresults = executor.invokeAll(tasks.map { task ->
Callable<Errorneous<R>> {
try { Success(task()) } catch (e: Exception) { Fail(e) }
}
})
return fresults.map { future -> future.get() }
}

Convert Data to String in Swift 3

I am very new to Swift.
I want to create something like API on Swift for my educational app.
I have this code:
static func getFilm(filmID: Int) -> String {
print("getFilm")
let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!
var request = URLRequest(url: url)
var returnData: String = ""
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if var responseVar = response, var dataVar = data {
print(responseVar)
returnData = String(data: dataVar, encoding: .utf8)
} else {
print(error)
}
}
task.resume()
return returnData
}
And I try to convert Data to String in this line: returnData = String(data: dataVar, encoding: .utf8)
Swift compiler gives me an error, and change this line to
returnData = String(data: dataVar, encoding: .utf8)!
, when I execute this line I get empty returnData variable.
If I use basic example line
print(String(data: data, encoding: .utf8))
everything will be OK and I can see data in XCode console.
So, how I can convert Data to String?
This is an example using a completion handler:
class func getFilm(filmID: Int, completion: #escaping (String) -> ()) {
let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!
URLSession.shared.dataTask(with:url) { (data, response, error) in
if error != nil {
print(error!)
completion("")
} else {
if let returnData = String(data: data!, encoding: .utf8) {
completion(returnData)
} else {
completion("")
}
}
}.resume()
}
And you call it
MyClass.getFilm(filmID:12345) { result in
print(result)
}
In case of an error the completion handler returns an empty string.
MyClass is the enclosing class of getFilm method. Most likely the web service will return JSON, so you might need to deserialize the JSON to an array or dictionary.
In a more sophisticated version create an enum with two cases and associated values
enum ConnectionResult {
case success(String), failure(Error)
}
With a little more effort demonstrating the subtle power of Swift you can return either the converted string on success of the error on failure in a single object.
class func getFilm(filmID: Int, completion: #escaping (ConnectionResult) -> ()) {
let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!
URLSession.shared.dataTask(with:url) { (data, response, error) in
if error != nil {
completion(.failure(error!))
} else {
if let returnData = String(data: data!, encoding: .utf8) {
completion(.success(returnData))
} else {
completion(.failure(NSError(domain: "myDomain", code: 9999, userInfo: [NSLocalizedDescriptionKey : "The data is not converible to 'String'"])))
}
}
}.resume()
}
On the caller side a switch statement separates the cases.
MyClass.getFilm(filmID:12345) { result in
switch result {
case .success(let string) : print(string)
case .failure(let error) : print(error)
}
}
I had this problem, you can't use encoding: .utf8 for unpredictable data. It will return nil every time.
Use this instead:
String(decoding: data, as: UTF8.self)
For anyone coming in future (which are probably not interested in OP's film code?!);
Simply, try something like:
extension Data {
public func toString() -> String {
return String(data: self, encoding: .utf8) ?? "";
}
}
See also my toHex related answer

Scala synchronized consumer producer

I want to implement something like the producer-consumer problem (with only one information transmitted at a time), but I want the producer to wait for someone to take his message before leaving.
Here is an example that doesn't block the producer but works otherwise.
class Channel[T]
{
private var _msg : Option[T] = None
def put(msg : T) : Unit =
{
this.synchronized
{
waitFor(_msg == None)
_msg = Some(msg)
notifyAll
}
}
def get() : T =
{
this.synchronized
{
waitFor(_msg != None)
val ret = _msg.get
_msg = None
notifyAll
return ret
}
}
private def waitFor(b : => Boolean) =
while(!b) wait
}
How can I changed it so the producers gets blocked (as the consumer is) ?
I tried to add another waitFor at the end of but sometimes my producer doesn't get released.
For instance, if I have put ; get || get ; put, most of the time it works, but sometimes, the first put is not terminated and the left thread never even runs the get method (I print something once the put call is terminated, and in this case, it never gets printed).
This is why you should use a standard class, SynchronousQueue in this case.
If you really want to work through your problematic code, start by giving us a failing test case or a stack trace from when the put is blocking.
You can do this by means of a BlockingQueue descendant whose producer put () method creates a semaphore/event object that is queued up with the passed message and then the producer thread waits on it.
The consumer get() method extracts a message from the queue and signals its semaphore, so allowing its original producer to run on.
This allows a 'synchronous queue' with actual queueing functionality, should that be what you want?
I came up with something that appears to be working.
class Channel[T]
{
class Transfer[A]
{
protected var _msg : Option[A] = None
def msg_=(a : A) = _msg = Some(a)
def msg : A =
{
// Reading the message destroys it
val ret = _msg.get
_msg = None
return ret
}
def isEmpty = _msg == None
def notEmpty = !isEmpty
}
object Transfer {
def apply[A](msg : A) : Transfer[A] =
{
var t = new Transfer[A]()
t.msg = msg
return t
}
}
// Hacky but Transfer has to be invariant
object Idle extends Transfer[T]
protected var offer : Transfer[T] = Idle
protected var request : Transfer[T] = Idle
def put(msg : T) : Unit =
{
this.synchronized
{
// push an offer as soon as possible
waitFor(offer == Idle)
offer = Transfer(msg)
// request the transfer
requestTransfer
// wait for the transfer to go (ie the msg to be absorbed)
waitFor(offer isEmpty)
// delete the completed offer
offer = Idle
notifyAll
}
}
def get() : T =
{
this.synchronized
{
// push a request as soon as possible
waitFor(request == Idle)
request = new Transfer()
// request the transfer
requestTransfer
// wait for the transfer to go (ie the msg to be delivered)
waitFor(request notEmpty)
val ret = request.msg
// delete the completed request
request = Idle
notifyAll
return ret
}
}
protected def requestTransfer()
{
this.synchronized
{
if(offer != Idle && request != Idle)
{
request.msg = offer.msg
notifyAll
}
}
}
protected def waitFor(b : => Boolean) =
while(!b) wait
}
It has the advantage of respecting symmetry between producer and consumer but it is a bit longer than what I had before.
Thanks for your help.
Edit : It is better but still not safe…

Calling Thread.sleep inside an actor

I have a function retry which basically looks like this (simplified):
object SomeObject {
def retry[T](n: Int)(fn: => T): Option[T] = {
val res = try {
Some(fn)
} catch {
case _: Exception => None
}
res match {
case Some(x) => Some(x)
case None =>
if (n > 1)
//make it sleep for a little while
retry(n - 1)(fn)
else None
}
}
}
I need to make some pause between the attempts. As I was told, it's not acceptable to call Thread.sleep(123) inside an actor:
class MyActor extends Actor {
//......
def someFunc = {
Thread.sleep(456) // it's not acceptable in an actor, there is another way to do it
}
}
Obviously, I don't know whether or not a client will use SomeObject.retry inside an actor:
class MyActor extends Actor {
//......
def someFunc = {
SomeObject.retry(5)(someRequestToServer) // ops, SomeObject.retry uses Thread.sleep!
}
}
So if I just add:
res match {
case Some(x) => Some(x)
case None =>
if (n > 1)
//make it sleep for a little while
Thread.sleep(123) // ops, what if it's being called inside an actor by a client?!
retry(n - 1)(fn)
else None
}
}
it won't be sensible, will it? If not, what do I do?
Yes, calling Thread.sleep is a bad idea as in an actor system threads are normally a limited resource shared between Actors. You do not want an Actor calling sleep and hogging a Thread from other Actors.
What you should do instead is use the Scheduler (see docs) to have your actor sent a message to itself sometime in the future to retry. To do this, you would have to move the retry code out of SomeObject and into the Actor
class MyActor extends Actor {
import context.system.dispatcher
def receive = {
case DoIt(retries) if retries > 0 =>
SomeObject.attempt(someRequestToServer) match {
case Some(x) => ...
case None =>
context.system.scheduler.scheduleOnce(5.seconds, self, DoIt(retries - 1))
}
}
}
Then if you were using SomeObject.try outside of an Actor System
def attempt(retries: Int) = {
SomeObject.attempt(someRequestToServer) match {
case Some(x) => ...
case None if retries > 0 => {
Thread.sleep(123)
attempt(retries - 1)
}
}
}
Where SomeObject.attempt is:
object SomeObject {
def attempt[T](fn: => T): Option[T] =
try {
Some(fn)
} catch {
case _: Exception => None
}
}

Resources