I'm pretty new to purescript and I have a simple purescript demo app that is running on AWS Lambda. I'm trying to get it to talk to S3, which is actually successful, however when the Aff callback finishes executing, the _makeAff javascript function tries to call its internal success callback an additional time. That call fails because success is undefined at that point so then it throws, hits the catch block, and when it tries to call error it throws again and the program terminates.
Here's a simple example to show how I have this set up:
Main.purs
-- I've tried
myTest "hello world!" >>= (\s -> log $ "from purs " <> s)
-- and
do
res <- myTest "hello world!"
log $ "from purs " <> res
Test.purs
module Lib.Test
(myTest)
where
import Control.Monad.Aff (Aff, makeAff, runAff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION, throwException, error, message, try)
import Control.Monad.Aff.Console (log)
import Prelude
foreign import myTestEff :: forall e . (String -> Eff e Unit) -> String -> Eff e Unit
myTest :: forall e . String -> Aff e String
myTest s = makeAff \reject resolve -> myTestEff resolve s
Test.js
"use strict";
// module Lib.Test
exports.myTestEff = function (cb) {
return function (s) {
return function () {
console.log("from js " , s);
cb(s)();
}
}
};
In the compiled index.js file that pulp makes, the error happens in the _makeAff function:
exports._makeAff = function (cb) {
return function(success, error) {
try {
return cb(function(e) {
return function() {
error(e);
};
})(function(v) {
return function() {
success(v); // i fail
};
})();
} catch (err) {
error(err); // then i fail
}
}
}
and this happens AFTER cb(v)(); is complete in Test.js, because I can see the console output from both js and purs in the lambda logs.
Thanks for any assistance.
From https://github.com/slamdata/purescript-aff/issues/54
... you can't use an Aff value directly as a main, you need to runAff or launchAff it to turn it into an Eff:
main = launchAff do
a <- later $ pure 42
b <- later' 1000 $ pure 58
pure $ a + b
Related
When I run the following snippet I don't see the backpressure.
public static void main(String[] args) throws InterruptedException {
MyFileProcessor pro = new MyFileProcessor();
Timer t = new Timer();
t.start();
Disposable x = pro
.generateFlowable(
new File("path\\to\\file.raw"))
.subscribeOn(Schedulers.io(), false).observeOn(Schedulers.io()).map(y -> {
System.out.println(Thread.currentThread().getName() + " xxx");
return y;
})
.subscribe(onNext -> {
System.out.println(Thread.currentThread().getName() + " " + new String(onNext));
Thread.sleep(100);
}, Throwable::printStackTrace, () -> {
System.out.println("Done");
t.end();
System.out.println(t.getTotalTime());
});
Thread.sleep(1000000000);
}
When I run the class above I get an alternating lines of
RxCachedThreadScheduler-1 xxx
RxCachedThreadScheduler-1 Line1
....
Its using the same thread.
Now when I move the observeOn to just before the subscribe, I see a bunch of
RxCachedThreadScheduler-1 xxx
Followed by a bunch of
RxCachedThreadScheduler-1 Line1
I am assuming this is back pressure but still the thread used is the same.
Why am I seeing this behavior?
Why is only one thread being utilized?
There is no operator as such for the observeOn to operate on, so why am I seeing this behavior?
[edit]
public Flowable<byte[]> generateFlowable(File file) {
return Flowable.generate(() -> new BufferedInputStream(new FileInputStream(file)), (bufferedIs, output) -> {
try {
byte[] data = getMessageRawData(bufferedIs);
if (data != null)
output.onNext(data);
else
output.onComplete();
}
catch (Exception e) {
output.onError(e);
}
return bufferedIs;
}, bufferedIs -> {
try {
bufferedIs.close();
}
catch (IOException ex) {
RxJavaPlugins.onError(ex);
}
});
}
Why is only one thread being utilized?
Works correctly because you check the running thread after observeOn and thus you are supposed to see the same thread there and below, no matter what happens above it. subscribeOn affects generateFlowable where, I suppose, you don't print the current thread and thus you don't see it runs on a different IO thread.
Now when I move the observeOn to just before the subscribe
There shouldn't be any difference unless something odd happens in generateFlowable.
I have the following bit of code where I'm using the RESTful framework for Go called sleepy.
I can successfully start the service at: http://localhost:3000, however when I try to access http://localhost:3000/temperature I'm expecting my SparkCore function dht to execute.
I'm using the Gobot.io Spark platform to execute this function based on this example, which I've implemented in my own code.
The problem is that the code doesn't get past the gobot.Start() method inside the Get() function so I can't actually return the result data.
I'm setting the data value hoping that I can do the:
return 200, data, http.Header{"Content-type": {"application/json"}}
But it never gets called becuase of the gobot.Start().
I'm very new to Go so any help would be greatly appreciated.
package main
import (
"net/url"
"net/http"
"fmt"
"github.com/dougblack/sleepy"
"github.com/hybridgroup/gobot"
"github.com/hybridgroup/gobot/platforms/spark"
)
var gbot = gobot.NewGobot()
var sparkCore = spark.NewSparkCoreAdaptor("spark", "device_id", "auth_token")
type Temperature struct {}
func (temperature Temperature) Get(values url.Values, headers http.Header) (int, interface{}, http.Header) {
work := func() {
if result, err := sparkCore.Function("dht", ""); err != nil {
fmt.Println(err)
} else {
data := map[string]string{"Temperature": result}
fmt.Println("result from \"dht\":", result)
}
}
robot := gobot.NewRobot("spark",
[]gobot.Connection{sparkCore},
work,
)
gbot.AddRobot(robot)
gbot.Start()
return 200, data, http.Header{"Content-type": {"application/json"}}
}
func main() {
api := sleepy.NewAPI()
temperatureResource := new(Temperature)
api.AddResource(temperatureResource, "/temperature")
fmt.Println("Listening on http://localhost:3000/")
api.Start(3000)
}
gbot.Start() is a blocking call.
In this context, you are expected to call it as:
go gbot.Start()
This will launch it in a goroutine (think thread) and then let your app continue.
When you look at the gobot example app, they don't run in the background since it is the main function. If main runs everything in the background and doesn't wait for anything, the app exits immediately with no apparent effect.
Helo,
at the beginning i wold like to apologize for my english :)
akka=2.3.6
spray=1.3.2
scalatest=2.2.1
I encountered strange behavior of teting routes, which asks actors in handleWith directive,
I've route with handleWith directive
pathPrefix("firstPath") {
pathEnd {
get(complete("Hello from this api")) ~
post(handleWith { (data: Data) =>{ println("receiving data")
(dataCalculator ? data).collect {
case Success(_) =>
Right(Created -> "")
case throwable: MyInternalValidatationException =>
Left(BadRequest -> s"""{"${throwable.subject}" : "${throwable.cause}"}""")
}
}})
}
}
and simple actor wchich always responds when receive object Data and has own receive block wrapped in LoggingReceive, so I should see logs when message is receiving by actor
and i test it using (I think simple code)
class SampleStarngeTest extends WordSpec with ThisAppTestBase with OneInstancePerTest
with routeTestingSugar {
val url = "/firstPath/"
implicit val routeTestTimeout = RouteTestTimeout(5 seconds)
def postTest(data: String) = Post(url).withJson(data) ~> routes
"posting" should {
"pass" when {
"data is valid and comes from the identified user" in {
postTest(correctData.copy(createdAt = System.currentTimeMillis()).asJson) ~> check {
print(entity)
status shouldBe Created
}
}
"report is valid and comes from the anonymous" in {
postTest(correctData.copy(createdAt = System.currentTimeMillis(), adid = "anonymous").asJson) ~> check {
status shouldBe Created
}
}
}
}
}
and behavior:
When I run either all tests in package (using Intellij Idea 14 Ultimate) or sbt test I encounter the same results
one execution -> all tests pass
and next one -> not all pass, this which not pass I can see:
1. fail becouse Request was neither completed nor rejected within X seconds ( X up tp 60)
2. system console output from route from line post(handleWith { (data: Data) =>{ println("receiving data"), so code in handleWith was executed
3. ask timeout exception from route code, but not always (among failed tests)
4. no logs from actor LoggingReceive, so actor hasn't chance to respond
5. when I rerun teststhe results are even different from the previous
Is there problem with threading? or test modules, thread blocking inside libraries? or sth else? I've no idea why it isn't work :(
I am migrating coffeeScript code from Q to Bluebird and it looks like I have been using promises all wrong, since Bluebird's documentation clearly discourages the use of Promise.defer
The simplified version of my client-server with Q is as follows:
Q = require 'q'
handleRequest = (msg) ->
console.log "Server received #{msg} \n"
deferred = Q.defer()
setTimeout () ->
deferred.resolve "bar"
, 2000
deferred.promise
handleRequest "foo"
.then (msg) ->
console.log msg
Basically I have a function with a promise that will be resolved asynchronously after 2 seconds.
When trying the same approach in Bluebird I get a TypeError saying that the Object function Promise(resolver) has no method 'then' (whole error code is at the end of this post)
Promise = require 'bluebird'
handleRequest = (msg) ->
console.log "Server received #{msg} \n"
new Promise (resolve) ->
"bar"
setTimeout () ->
Promise.resolve()
, 2000
Promise
handleRequest "foo"
.then (msg) ->
console.log msg
I don't know where I am messing it up since Bluebird's documentation for creating a new Promise seems to be just that, a function with resolve/reject functions.
I haven't been able to find any similar approach of promises creation without using promisify.
EventEmitters can do the trick but I really need to use promises in the big version.
There are some other bits of code where the same flow is used: a function where a defer is created/returned and it will be resolved/rejected at some stage.
Thank you very much in advance!!! :)
I have been struggling with this the whole morning.
Server received foo
TypeError: Object function Promise(resolver) {
if (typeof resolver !== "function") {
throw new TypeError("the promise constructor requires a resolver function");
}
if (this.constructor !== Promise) {
throw new TypeError("the promise constructor cannot be invoked directly");
}
this._bitField = 0;
this._fulfillmentHandler0 = void 0;
this._rejectionHandler0 = void 0;
this._promise0 = void 0;
this._receiver0 = void 0;
this._settledValue = void 0;
this._boundTo = void 0;
if (resolver !== INTERNAL) this._resolveFromResolver(resolver);
} has no method 'then'
Googling the error led me to this page of Bluebird's documentation.
So I understand that the async part of the code is the resolution of the promise itself, thus rewriting the code like shown below fixes this issue:
Promise = require 'bluebird'
handleRequest = (msg) ->
new Promise (resolve) ->
setTimeout () ->
resolve "bar"
, 2000
handleRequest "foo"
.then (msg) ->
console.log msg
I'm using Iced coffescript with upshot js when I am refreshing multiple data sources. The refresh method has TWo call backs one for success and one for error and I want to wait for each call to make either callback.
I can't see how to do this with idced coffescript without making an additional function. My question is - is there a more elegant way that I can defer to one of multiple callbacks?
This is the code I have currently:
refreshMe = (key, value, result) =>
value.refresh(
(success)=>
result success
,
(fail, reason, error)=>
result undefined, fail
)
#refresh = () =>
success={}
fail={}
await
for key, value of #dataSources
refreshMe key, value, defer success[key], fail[key]
This is the only way I have found to do it too. I'm using it in Backbone and wrap (for example) a model's #save function with an #icedSave:
# An IcedCoffeescript friendly version of save
icedSave: (callback) ->
#save {},
success: (model, response) -> callback(true, model, response)
error: (model, response) -> callback(false, model, response)
Here's some code I use for converting Promises .then (-> onSuccess), (-> onError) to errbacks (err, result) ->:
# You can write like this:
await value.refresh esc defer e, result
# onError - function to be called when promise rejected.
# onSuccess - function to be called when promise is fulfilled.
module.exports = esc = (onError, onSuccess) ->
util = require 'util'
return (result) ->
if util.isError result
# Always send back an error to first handler.
onError? result
else if onSuccess?
console.log onSuccess, result
# `await fn esc done, defer result`
onSuccess? result
else
# `await fn esc done`
onError? null, result
You could modify the esc function a bit to handle multiple arguments for each callback.
iced.Rendezvous lib is made explicitly for this case: return at the first of multiple callbacks. From the docs:
Here is an example that shows off the different inputs and outputs of
a Rendezvous. It does two parallel DNS lookups, and reports only when
the first returns:
hosts = [ "okcupid.com", "google.com" ];
ips = errs = []
rv = new iced.Rendezvous
for h,i in hosts
dns.resolve hosts[i], rv.id(i).defer errs[i], ips[i]
await rv.wait defer which
console.log "#{hosts[which]} -> #{ips[which]}"