Skip to content

Instantly share code, notes, and snippets.

@evantahler
Created May 11, 2016 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evantahler/22e434cdc5f109a8aa38c4a4fccf12ac to your computer and use it in GitHub Desktop.
Save evantahler/22e434cdc5f109a8aa38c4a4fccf12ac to your computer and use it in GitHub Desktop.
Actionhero Gitter Chat History [Sep 13 2014 - May 10 2016]
Evan Tahler @evantahler Sep 13 2014 09:38
Welcome to the actionhero room!
Pablo Jairala @davidjairala Sep 16 2014 14:51
hello people
Evan Tahler @evantahler Sep 16 2014 14:57
We announced this gitter room to the google group @ https://groups.google.com/forum/#!topic/actionhero-js/EONsyvCDBDc
Evan Tahler @evantahler Sep 17 2014 08:57
Cool! we have some new members here. What is everyone working on? Anyone have any questions?
Mike Bartlett @mydigitalself Sep 17 2014 08:58
just browsing actually, mike here from Gitter :smile:
curious about actionhero though, will certainly take a look at it in the future, we were looking at something more API specific for our own use. we’re currently on express for just about everything. do you have any materials on actionhero vs express vs hapi for example out of interest?
salles @sallespro Sep 17 2014 09:02
hi Evan, just working on the clustering of action hero now.
dunse @dunse Sep 17 2014 09:04
In bau mode atm.. have actionhero as the backend for self provisioning of dev environments in aws.. works great!
salles @sallespro Sep 17 2014 09:05
@mydigitalself actionhero allows very good code architecture dividing actions, tasks for background operations and many really interesting features you’ll be glad to discover and it’s been a plus from express in my use cases. but the most important is this guy behind it... @evantahler
dunse @dunse Sep 17 2014 09:07
@evantahler in regards to new demo app. Might be good to have something using mongo and passport.. load models in similar ways actions and allow connect.io style passport for user authentication.
Mike Bartlett @mydigitalself Sep 17 2014 09:11
ah, @evantahler do you know Yee Lee?
Evan Tahler @evantahler Sep 17 2014 09:11
hey @mydigitalself I don't think I have any comparisons on speed vs express, but I do here a lot folks say what @sallespro says, in that they like the project organization better. If you are looking for a pure API server (no views) and want to support both HTTP and WS with the same code, give it a try!
Check out this example project which might be a good refrence https://github.com/evantahler/actionhero-tutorial or this silly chat program https://github.com/evantahler/earlyagain
@dunse that would be cool. I personally tend to avoid mongo, but if you have any examples, please share them!
@sun
@dunse I'm more of a mySQL / Postgres guy: https://github.com/evantahler/ah-sequelize-plugin
dunse @dunse Sep 17 2014 09:16
@evantahler fair enough. I'll see what I share...
Evan Tahler @evantahler Sep 17 2014 09:18
Thanks @trevorah for fixing all my grammar and spelling mistakes!
@mydigitalself if you guys are in the Bay Area, I'd be happy to help out with you AH exploration.
salles @sallespro Sep 17 2014 09:44
@evantahler have you heard of any actionheroClient & angularjs integration / wrapping ?
Evan Tahler @evantahler Sep 17 2014 17:06
@sale
@sallespro no, not personally, but here are some notes https://groups.google.com/forum/#!searchin/actionhero-js/angular/actionhero-js/AgJKIrzEF3Y/00CIcuJh4KMJ
Evan Tahler @evantahler Sep 18 2014 16:37
oh, speaking of angular @sallespro, @S3bb1 made a whole dashboard plugin for actionhero with it https://github.com/S3bb1/ah-dashboard-plugin
salles @sallespro Sep 18 2014 17:42
@evantahler oh, great, didnt know about it. thanks !
Evan Tahler @evantahler Sep 18 2014 20:02
Evan Tahler @evantahler Sep 18 2014 23:00
Heh, I wanted to play some more with angular, so here are some examples http://actionherojs.com/docs/examples/clients/angular.html
Sebastian Dechant @S3bb1 Sep 19 2014 05:44
Nice @evantahler ... so ActionHero will become a webApp server too :)
salles @sallespro Sep 19 2014 07:07
@S3bb1 thanks for the beautifully crafted code in the dashboard. @evantahler thanks for the kickstart angular code, one thing to look at, angular wise, is ngResource.
Sebastian Dechant @S3bb1 Sep 19 2014 11:49
Thank you @sallespro ... I will work on new features for the dashboard. I hope I can soon release the redis viewer for the dashboard.
Evan Tahler @evantahler Sep 19 2014 16:56
There's a cool thread on the mailing list comparing AH to Express... what are your thoughts? https://groups.google.com/forum/#!topic/actionhero-js/Q_PwGONycc0
omichowdhury @omichowdhury Sep 19 2014 21:05
Anyone tried running AH on beanstalk?
we're having issues where start works but startcluster doesn't
the workers exit as soon as they spawn, leaving no logs behind
omichowdhury @omichowdhury Sep 19 2014 22:23
we figured out the issue above - there's a difference in the way that NODE_ENV is handled between start and startCluster
not sure exactly what was going wrong, will dig into it - but we're up!
omichowdhury @omichowdhury Sep 19 2014 22:31
gonna be doing some load and auto-scaling testing over the next week, would still love to talk to anyone who's running AH using the node container for AWS EB
Evan Tahler @evantahler Sep 22 2014 10:02
I've not use ElasticBeanstalk before, but I imagine that it would be best not to use actionCluster. If each EB instance is meant to be a single 'node' (single CPU), then using cluster in this case would probably hurt performance.
Let us know what you learn!
omichowdhury @omichowdhury Sep 22 2014 10:27
I think our boxes have 2 cores so Im running 2 instances with 2 workers on each box - lots of tuning to be done
omichowdhury @omichowdhury Sep 22 2014 10:35
well 0 workers on the load balancer facing instances
salles @sallespro Sep 22 2014 11:18
about the Express / AH anti-comparison
AH is that pretty collection of hand crafted pieces that will seem obvious for those who know what one's looking for and get to know AH for what it is.
Wiebe Niehof @wniehof Sep 28 2014 09:21
Good day. I'm using actionhero for the first time together with Sequelize. Also use the plugin of @evantahler. Sync this plugin doesn't support the sync functionality I was looking at 'migrations' in sequelize to create a table in MySQL. However I don't get it work and can't find any more information or examples how to integrate this with actionhero. Does anybody know a good working example of this? Thanks!
Evan Tahler @evantahler Sep 28 2014 09:54
I've updated the readme a little bit.
@wniehof If you want to sync, you can api.sequelize.sync() or api.models.yourModel.sync()
and here is a migrations example
// from ./migrations/20140101000001-create-users.js
module.exports = {
up: function(migration, DataTypes, done) {
migration.createTable('users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: DataTypes.STRING,
email: DataTypes.STRING,
phone: DataTypes.STRING,
passwordHash: DataTypes.TEXT,
passwordSalt: DataTypes.TEXT,
createdAt: DataTypes.DATE
updatedAt: DataTypes.DATE
}).complete(function(){
migration.addIndex('users', ['email'], {
indexName: 'email_index',
indicesType: 'UNIQUE'
}).complete(function(){
migration.addIndex('users', ['name'], {
indexName: 'name_index',
indicesType: 'UNIQUE'
}).complete(function(){
migration.addIndex('users', ['phone'], {
indexName: 'phone_index',
indicesType: 'UNIQUE'
}).complete(function(){
done();
});
});
});
});
},
down: function(migration, DataTypes, done) {
migration.dropTable('users').complete(done);
}
}
Evan Tahler @evantahler Sep 28 2014 10:00
(also added to the readme @wniehof)
Wiebe Niehof @wniehof Sep 29 2014 12:38
Hi @EventAhler. Thanks for this. I got it to work. Migrations in Sequelize do seem to work a little bit different than I thought / hoped. For every migration action it seems you have to create a separate migration file. I was looking at a solution to create tables dynamically, triggered by an API call. Maybe I should just use a raw MySQL query for this? And is that even possible within this Actionhero plugin?
Wiebe Niehof @wniehof Sep 29 2014 14:17
Ah I noticed that "api.models.yourModel.sync()" & "api.models.yourModel.drop()" works much better for my scenario. Now let's see if I can get it as dynamic as I wanted..
Evan Tahler @evantahler Sep 29 2014 15:04
Cool!
Wiebe Niehof @wniehof Sep 29 2014 15:08
Do you maybe know if it's possible to add variables to the "api.models.yourModel.sync(variable)" which I can use as a TableName in the Model?
Evan Tahler @evantahler Sep 29 2014 18:06
Not right now, but it should be easy to add. Send in a pull request! @wniehof
Wiebe Niehof @wniehof Sep 29 2014 23:22
Ok, great. I will do that, today or tomorrow. Thanks again!
Evan Tahler @evantahler Sep 30 2014 17:40
@all As a reminder, if you are using actionhero at work, it would be awesome to be able to list more companies on the actionherojs.com homepage. Please let me know if I can list your company!
Wiebe Niehof @wniehof Oct 01 2014 09:27
@evantahler If it would ever grow out into a company / solution I would certainly let you know ;-). Ps. I created a Pull Request, however I do think I need some hints / help from you to get this finished..
Sebastian Dechant @S3bb1 Oct 03 2014 12:32
@sallespro i've recently pushed the redis viewer to the ah-dashboard-plugin. If you want to test it, simply checkout the feature_redisviewer branch. The full version will pushed this weekend to the npm
Fadi Abu Alnaser @fadiabualnaser Oct 08 2014 03:24
hello all, i need more documation about actionCluster any help please
Evan Tahler @evantahler Oct 08 2014 07:00
@fadiabualnaser what's the question?
chimmelb @chimmelb Oct 10 2014 11:57
Where would be a good place to specify a startup procedure? Example: On startup I want to populate the cache with some DB data (so each user doesn't need to hit the DB, and a service or tasks queries the DB periodically to update the cache). I want that cache population to happen after all initializers, actions, routes, etc.
omichowdhury @omichowdhury Oct 10 2014 12:08
I do that in an _start function in an initializer
do db connections and such when the initializer is loaded by actionhero, and _start functions will get called after all the initializers have loaded
@chimmelb
chimmelb @chimmelb Oct 10 2014 12:12
Thanks @omichowdhury I didn't realize that about _start() methods. An initializer seemed like the place (by name) but wanted to make sure.
Is there a way to rank initializers to ensure order? (Now I'm asking out of curiosity, no real need for it yet)
Evan Tahler @evantahler Oct 10 2014 16:06
Alphabetical @chimmelb
Evan Tahler @evantahler Oct 12 2014 19:35
I just did a big LINT refactor of actionhero. Please try out the branch in the next few days and make sure I didn't break anything! evantahler/actionhero#476
omichowdhury @omichowdhury Oct 13 2014 13:04
Is there a way of pulling a PR using npm? that'd be sweet
Mike Bartlett @mydigitalself Oct 13 2014 13:08
you can point your package.json to a git url can’t you… not sure if that helps?
omichowdhury @omichowdhury Oct 13 2014 15:46
thanks @mydigitalself , "actionhero": "git://github.com/evantahler/actionhero.git#lint" worked
@evantahler No issues detected in my app
Evan Tahler @evantahler Oct 13 2014 17:21
awesome! Thanks for checking it out @mydigitalself @omichowdhury
for actionhero newbies, we now have a 1-click "try me on heroku" button https://github.com/evantahler/actionhero#quick-start
salles @sallespro Oct 14 2014 17:41
i am trying to use Passport, ( https://gist.github.com/juancgarcia/e4caf5dc7474769f5137)
i can’t understand how the action preProcessor has to dela with a login action
salles @sallespro Oct 14 2014 19:48
@evantahler i am missing some of my custom initializers being loaded.
i am using using @S3bb1 dashboard plugin too.
omichowdhury @omichowdhury Oct 15 2014 05:44
@sallespro Looking at that gist it looks like there is no specific login action. Preprocessors run on every action. If an action has an authenticated flag, then the doBasicAuth function is called. This is what is used to log someone in (using Basic Auth). You can write a login action if you want. It would need to call passport.authenticate, and could then use params to log in. Then you can tweak the preprocessors to only check authentication but delete their logging in code.
salles @sallespro Oct 15 2014 07:37
@omichowdhury a few things are going on : why wouldn’t a initializer, with its .js file properly named as the export be loaded ? i occurred to me that it should be turned into a plugin and declared in api.js.
Another “not so clear” is wether the actionTemplate should use a specific flag authenticate(d) ? Another difference from the examples is how to addPreProcessor or do the push...
omichowdhury @omichowdhury Oct 15 2014 08:44
@sallespro Add some console logging at the top level of the file to check that the file itself is being loaded. Remember that just loading the file doesn't do anything to the api object. You have to explicitly set with api.myThing = {...}
actionTemplates do need an authenticated flag if they require login (and therefore will allow you to login). An actionTemplate without authenticated set won't require login but also cannot be used to log in
Evan Tahler @evantahler Oct 23 2014 10:57
Anyone here use the Swagger API spec? I'm writing an actionhero middleware for it
evantahler/actionhero@112314a
I'd love some advice on the spec... what parts are required, which are optional, etc
Devin Despain @dangerdespain Oct 23 2014 11:22
be aware that the demo on their site is still using the v1.2 spec
I definitely wasted a bit of time before realizing that it wasn't running at the current v2 spec
Evan Tahler @evantahler Oct 23 2014 11:55
yeah, I'm aiming for 2.0
also, evantahler/actionhero@d2804f3 If you are using actionhero at work, include it on the website!
chimmelb @chimmelb Oct 23 2014 13:47
I haven't created a swagger doc, but we did use swagger-node-restify on my last project. Restify was our API server, and every route had a "spec" that was used to build the swagger docs.
I put some comments in ticket #44, let me know if I can give you any more info.
Jason Marmon @jtmarmon Oct 24 2014 16:03
quick question (didn't want to open an issue without asking first) - is it possible to support routes that don't go through the 'urlPathForActions' path? I'm refactoring my current API and i need to be able to support the old paths that don't go through /api/*
Evan Tahler @evantahler Oct 24 2014 17:52
@jtmarmon Do you want 2 routes /api and /app to both go actions? Something else? Either way... probably need a PR for that one
salles @sallespro Oct 24 2014 18:40
@jtmarmon i suggest using a http-proxy to do the routing to the two APIs.
Jason Marmon @jtmarmon Oct 24 2014 20:43
@evantahler I would like /api/path to be linked to path v1 and /path to be linked to path v0
if possible (and reasonable in how long it would take). if it's not i can just support the old API and have v1 hosted elsewhere and start versioning from then on
Evan Tahler @evantahler Oct 26 2014 16:33
Well, if you make th api the base route you could do "deep" routes like that. I think I like the proxy suggestion better with two apps
Jason Marmon @jtmarmon Oct 26 2014 19:04
got it makes sense. thanks you two :)
chimmelb @chimmelb Oct 29 2014 06:24
Is there an intention in actionhero to chain actions? Or have tasks run actions? (I feel like the required connection object would be hard/impossible to replicate in a task)
Evan Tahler @evantahler Oct 29 2014 08:02
@chimmelb not really. That's kind of like asking if one Rails controller can call another. If you have a shared operation or model, you should move it out into an initializer. This way, you will end up with small actions and tasks that just call common methods.
(that's why the connection object is not portable)
salles @sallespro Oct 29 2014 10:14
@chimmelb AH has been helpful for me using actions to run tasks that use api.something as defined in the initializers.
Jason Marmon @jtmarmon Oct 29 2014 10:41
what's the best way to test a preprocessor for a route?
Jason Marmon @jtmarmon Oct 29 2014 10:48
I have a preProcessor that handles authentication so would the best way be to just write dummy routes with multiple access levels and run those?
Jason Marmon @jtmarmon Oct 29 2014 12:02
weird error: Uncaught TypeError: Cannot read property 'name' of undefined when running tests
doesn't happen when I run via npm start. coming from /node_modules/actionhero/initializers/actions.js:94:40
salles @sallespro Oct 29 2014 15:29
i am trying to enqueue a task that runs an Action, using this code and i get this error. 2014-10-29 18:25:06 - error: ! TypeError: Cannot read property 'attributes' of undefined 2014-10-29 18:25:06 - error: ! at api.connection.destroy (/home/me/node/ah/node_modules/actionhero/initializers/connections.js:164:14) 2014-10-29 18:25:06 - error: ! at api.actionProcessor.callback (/home/me/node/ah/tasks/runAction.js:26:18)
the task creates a new connection and attaches the params, but it seems to be missing some attributes ?
https://github.com/evantahler/actionhero/blob/master/tasks/runAction.js
salles @sallespro Oct 29 2014 16:18
.. avoiding connection.destroy eliminates the error.
Jason Marmon @jtmarmon Oct 29 2014 16:25
still no dice with my error - seems weird that it's unable to boot an action in the test env but works fine in development
Evan Tahler @evantahler Oct 29 2014 18:13
Probably has to do with the spec helper. Share the code?
Jason Marmon @jtmarmon Oct 29 2014 19:19
is there something specific you're thinking about? the repo itself is private
Evan Tahler @evantahler Oct 30 2014 00:06
well, that error from line 94 probably refrences this line https://github.com/evantahler/actionhero/blob/master/initializers/actions.js#L81, and that means you seem to have defined an action somewhere with out the name attribute
@sallespro per the above, you really shouldn't run an action from a task, or another action. whatever method you have, move it into an intializer
salles @sallespro Oct 30 2014 07:05
@evantahler when i saw the runAction example, it occurred to me it would be appropriate to run any Action that i didn’t want only to be invoked by a connection. if i understand, i should build both, an Action and a Task that would call whatever method my initializer defines, is that it ?
Evan Tahler @evantahler Oct 30 2014 07:40
Yeah
That's cleaner @sallesori
Jason Marmon @jtmarmon Oct 30 2014 08:07
@evantahler Well it would seem that it's not an action without a name but rather a file without an action (since the object on which actions.js to access name is "undefined". The weird thing is that this error should also occur during production or development, but the error is only during testing
Evan Tahler @evantahler Oct 30 2014 08:14
@jtmarmon wacy! Lets keep talking about it over here evantahler/actionhero#497
*wacky
Jason Marmon @jtmarmon Oct 30 2014 11:02
@evantahler pull request submitted
Devin Despain @dangerdespain Oct 30 2014 12:19
I've created a parameter validation plugin based off of chriso's validator.js library - check it out here https://github.com/dangerdespain/ah-validator-plugin
feedback is absolutely welcomed!
I'll wait to push a link to the gh-pages until I get the chance to actually use this for a while
Evan Tahler @evantahler Oct 30 2014 14:07
@dangerdespain that's cool!
Devin Despain @dangerdespain Oct 30 2014 16:03
thank you!
Amine Mouafik @kytwb Oct 31 2014 07:53
hi there
Evan Tahler @evantahler Oct 31 2014 09:46
hello! @kytwb
@dangerdespain regarding your validator, I still think integrating something like that into actionhero's core would be cool. if action.inputs.optional = ['key', 'value'] we do what we do now, but action.inputs.optional = [{name: key, type: string, ....} ] we use this new system
Harlan Milkove @harlanmilkove Oct 31 2014 12:17
hello @evantahler! I've been running an action hero instance on ec2 for a couple of months. Periodically (every couple of weeks) it will stop responding to requests. I don't see anything at all in the logs. I've been killing the pid and actionhero will automatically restart itself and everything looks great after that. We've had various versions, but are now on 9.4. Have you heard of this or experienced it?
We're just using it for prototyping, and most of the time no requests or connections are being served. We run with a web, websocket, and socket server on.
Most of the time it's just an AWS ELB pinging the instance with health checks. This was the case for the past two occurrences.
the health checks hit the /status route
Evan Tahler @evantahler Oct 31 2014 14:29
@harlanmilkove that's pretty strange. Are you on a micro node? I know that sometimes those nodes get "frozen", and we don't have any 'recovery' code.
And you have no tasks @harlanmilkove
?
Harlan Milkove @harlanmilkove Oct 31 2014 15:53
We upgraded to a small instance thinking that could have between the issue a while back. @evantahler
No tasks
Evan Tahler @evantahler Nov 01 2014 10:40
Very strange. Http or ws? If there's any way you find to reproduce it, let me know.
Oh! What OS and node version? There's a couple of things like this which might be related. joyent/node#5504
Amine Mouafik @kytwb Nov 02 2014 01:47
hi
i was using fakeredis in local, forgot to configure real redis in production and saw that every call to api.tasks.enqueue just crash the server (almost no load)
new relic show me a spike in cpu/memory usage to 100%
then complete crash of the ec2 instance, need to reboot it through aws cpanel
Amine Mouafik @kytwb Nov 02 2014 03:29
still crashing with real redis configured
Amine Mouafik @kytwb Nov 02 2014 03:40
ahah, now it's even worse; configured the real redis database, try to run the task, crash, reboot, retrieve the previous tasks from the redis database, re-crash, [insert infinite loop here]
any idea why tasks would do that?
Sebastian Dechant @S3bb1 Nov 02 2014 03:42
do you have any error messages, what crashed exactly ?
Amine Mouafik @kytwb Nov 02 2014 03:42
(I just use the tasks showed in ah-nodemailer-example)
it doesn't crash, just take 100% memory
but server become unusable and need to reboot
Sebastian Dechant @S3bb1 Nov 02 2014 03:46
do you have tried any other task, maybe only prints out "Hello World" for example ?
maybe there's something wrong with the nodemailer plugin
Amine Mouafik @kytwb Nov 02 2014 03:53
i'll try that
when I use nodemailer directly it works perfectly though
just when i try to defer email sending in a task
Evan Tahler @evantahler Nov 02 2014 16:45
@kytwb how big is the payload of the task you are enqueuing? Either way, run the server in 'debug' mode to sort out where the crash is happening... the "enqueue" step or the "work" step
Evan Tahler @evantahler Nov 03 2014 08:01
Testing the gitter mobile app...
Harlan Milkove @harlanmilkove Nov 03 2014 09:52
hi @evantahler. hope you had a good weekend! I'm experiencing that issue on ubuntu 14.04. Node v0.10.31. I'm running with HTTP, WS, and Socket servers enabled. We use all three types of servers, but only the HTTP call is in any regular use before observing the problem. I haven't figured out how to reproduce the problem.
And by regular use, I mean an AWS health check against the status route every 30 seconds.
During periods of anything resembling actual load, I haven't seen any unresponsiveness.
Evan Tahler @evantahler Nov 03 2014 15:23
@harlanmilkove Sadly, this looks like a case for extreme debugging. Run the server manually in a screen with npm start (to bypass the cluster). Turn on debug logging... add a task that calls api.log every second... I've not seen anything like you have here (other than my OSX laptop going to sleep). Good luck!
what's the ram footprint of the app when it becomes unresponsive @harlanmilkove ?
Amine Mouafik @kytwb Nov 04 2014 02:19
@evantahler good call, i'll reproduce with debug mode on.
by the way, there's a problem in evantahler/ah-sequelize-plugin related to api.project_root
i forked, fixed for myself (replaced by api.projectRoot) and updated my package.json to my fork for now, I'm not sure if my patch is the best
i'll open the issue though
Amine Mouafik @kytwb Nov 04 2014 02:25
done
Harlan Milkove @harlanmilkove Nov 04 2014 07:18
Thanks for the advice @evantahler, I'll see if I can suss out the culprit that way.
Jason Marmon @jtmarmon Nov 04 2014 07:18
godspeed @harlanmilkove
Harlan Milkove @harlanmilkove Nov 04 2014 07:22
thanks Jason ;)
Evan Tahler @evantahler Nov 04 2014 09:09
@kytwb new version of the sequelize plugin up
Amine Mouafik @kytwb Nov 04 2014 22:18
thumbs up!
Devin Despain @dangerdespain Nov 04 2014 22:53
@evantahler that's the original direction that I was going but it seemed like it would be a bit of a lift to get that implemented system-wide since there are so many functions that expect an array of strings for action.inputs.required and .options
Devin Despain @dangerdespain Nov 04 2014 22:59
perhaps that array of strings could be generated and stored on the side to feed those functions? most of them seemed to be contained in things like documentation generation and test coverage but maybe the rewrite is worth it since the documentation stuff is being refactored (?) is there anything new on the horizon for actionsView/self-documentation?
testing the waters with a plugin seemed like a good middle ground to see if it'd gain any traction :)
Evan Tahler @evantahler Nov 05 2014 07:16
There's nothing too crazy that I'm doing with documentation. I'm still
Still experimenting with a swagger plugin, but that only works for http, so It can't replace the base documentor
Devin Despain @dangerdespain Nov 05 2014 11:48
there are some compelling tools in the api-blueprint space as well http://apiblueprint.org/#full_api
Evan Tahler @evantahler Nov 05 2014 12:53
Interesting @dangerdespain any clue which is more popular?
It's funny to me how we are getting dangerously close to soap. Don't get me wrong, xml is the worst, json is the best, as is rest. But the documentation bits are interesting.
Devin Despain @dangerdespain Nov 05 2014 13:48
well, it compiles to json
but I wonder if there's a tool to compile json to markdown
Evan Tahler @evantahler Nov 07 2014 11:31
So what do ya'll think about generator code style? evantahler/actionhero#508
Sebastian Dechant @S3bb1 Nov 07 2014 11:33
yeah, agree with this.. maybe https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml can be applied to the whole project ? ... i think this makes it more readable and the project has a consistent code style
Evan Tahler @evantahler Nov 07 2014 12:02
Well, the project passes a LINT test now, which is much better. Both functional-style and object-style definitions are valid, so it really becomes a community choice
Sebastian Dechant @S3bb1 Nov 07 2014 12:03
maybe the whole community can contribute to this :smile:
Jason Marmon @jtmarmon Nov 07 2014 15:54
yeah i'm a fan of the less verbose way. concision usually helps me when i'm a beginner to things anyway. i'll see if i can submit a PR sometime this weekend if no one has gotten to it by then
Jason Marmon @jtmarmon Nov 07 2014 16:00
@evantahler what do you think about including a jshint configuration in the actionhero project generator? seems like it would make sense if all the generated code is written in that style
Ahmed Abdelaliem @me2resh Nov 07 2014 17:11
Hey, I am new to actionhero and have a question. for mongoskin, where do i put the configuration https://www.npmjs.org/package/actionhero-mongoskin?
I tried configs/api.js but it didn't work
Evan Tahler @evantahler Nov 07 2014 17:32
@panjiesw Come to the room and help out with your packages!
@jtmarmon I'm down with a jshint file... I just used the defaults :grinning:
Ahmed Abdelaliem @me2resh Nov 07 2014 17:34
@panjiesw, @evantahler I think the initialiser is not updated with the new conf syntax
compatible with version earlier than 7 ?
@evantahler is there another package available to connect to mongo ?
Evan Tahler @evantahler Nov 07 2014 17:55
Sorry, I don't use mongo, so I haven't been paying attention :sheep:
Panjie Setiawan Wicaksono @panjiesw Nov 09 2014 07:11
Sorry guys, my work these recent months have successfully deviated me from Node.js, thus my published actionhero packages looks like a wrecked ship. Actionhero meanwhile, is moving fast and that is a job well done by @evantahler and other contributors. I will definitely catch up to the new actionhero version and fix my packages including actionher-mongoskin accordingly.
chimmelb @chimmelb Nov 11 2014 11:19
Is the correct way to send "complex payloads" (i.e. JSON docs) in the chat system simply to JSON.stringify the message prior to api.chatRoom.broadcast? I'd like to send events to everyone in the room ("user has left", "user has joined", etc)
Evan Tahler @evantahler Nov 11 2014 11:57
@chimnelb yep!
Check 'errors'. There's also some in/out messages you can toggle
Whoops. That was an old version.
Here's' what you want:
api.chatRoom.addJoinCallback = function(func, priority){
http://actionherojs.com/docs/core/chat.html#middleware
Evan Tahler @evantahler Nov 12 2014 12:39
Where have yall deployed actionhero? I want to make a list.
Sebastian Dechant @S3bb1 Nov 12 2014 12:43
IISNode or you mean special websites
Evan Tahler @evantahler Nov 12 2014 13:51
I guess I mean OS/hosting providers. Like Ubuntu 12 on Amaxon.
omichowdhury @omichowdhury Nov 12 2014 13:58
we're on ubuntu 14.04 on Amazon ElasticBeantalk
Devin Despain @dangerdespain Nov 12 2014 14:26
igniter.io!
Ubuntu on DigitalOcean
Evan Tahler @evantahler Nov 12 2014 16:15
Ooh. Can you share any learnings about elasticbeanstalk? (Mailing list, longer form)
And is the product live? What is it?
Thanks danger! What do you use for deployment?
Amine Mouafik @kytwb Nov 12 2014 21:29
Ubuntu 14.04 / Amazon EC2 instance
Within a Docker container (if that matter)
chimmelb @chimmelb Nov 13 2014 12:34
@kytwb Would you be willing to share your docker container? That would be a nice AH resource.
From my note earlier this week, I found out messages on a chat broadcast can be a JSON doc. Thankfully api.chatRoom.broadcast checks for message.length===0, and undefined doesn't match. (Please don't change ; ) That saved a messy double-parse on client-side, so I'm happy it works this way.
omichowdhury @omichowdhury Nov 13 2014 12:58
Can't say too much about the product publicly right now, read what you want from this link
http://blog.talkingidentity.com/2014/10/scuid-new-home-ca-technologies.html
It is live, we're still going through load testing, haven't really stressed the actionhero based components quite yet - the 4 server cluster (2 worker instances, 2 web instances) handled the tests fine, but those tests were stressing the DB mostly
Devin Despain @dangerdespain Nov 13 2014 19:10
we'll be figuring out our deployment stuff soon, we'll be launching a closed beta by the end of the year
hence the flurry of quick'n'dirty hacks coming from my forks ;)
Amine Mouafik @kytwb Nov 13 2014 21:49
@chimmelb you can run AH within any container based on dockerfile/nodejs (or other nodejs image)
Amine Mouafik @kytwb Nov 13 2014 22:00
@evantahler can you publish a patch for this on npm? evantahler/actionhero@48123af
Evan Tahler @evantahler Nov 14 2014 10:50
v9.4.1 is up https://github.com/evantahler/actionhero/releases/tag/v9.4.1
Devin Despain @dangerdespain Nov 14 2014 14:28
nice! stoked about the updated task error reporting
Jason Marmon @jtmarmon Nov 14 2014 15:30
using actionhero at a hackathon this weekend to build a CLI for Slack
Evan Tahler @evantahler Nov 14 2014 18:04
Nice!
Amine Mouafik @kytwb Nov 15 2014 03:21
api_1 | 2014-11-15 11:18:53 - debug: 0 routes loaded from undefined
api_1 | 2014-11-15 11:18:53 - debug: 89 simple routes loaded from action names
tries with routes.js in project root or in ./config/, same same
Amine Mouafik @kytwb Nov 15 2014 03:32
I don't get:
api.routes.loadRoutes = function(rawRoutes){
and right below:
api.routes.loadRoutes();
rawRoutes always undefined
leads to
api.log(counter + ' routes loaded from ' + api.routes.routesFile, 'debug');
routesFile is never set anywhere (https://github.com/evantahler/actionhero/search?utf8=%E2%9C%93&q=api.routes.routesFile)
Got it, gotta set api.config.routes
Amine Mouafik @kytwb Nov 15 2014 03:37
Sorry for the noise here :)
chimmelb @chimmelb Nov 20 2014 10:40
Is the correct way to put a value on a TCP connection for later actions (inside an action) connection._originalConnection.userId = user.id; I'm unsure if using that 'private' attrib was cheating : )
Harlan Milkove @harlanmilkove Nov 20 2014 12:01
Hi @chimmelb, I use connection.id to identify TCP connections. Works well for me :)
oh I see your question is a little different. I don't place values on a connection like that. I manage an object on the server keyed off the id
Amine Mouafik @kytwb Nov 27 2014 10:05
hey guys, just being curious
i know it depends on a lot of things, but can you guys tell me more about your AH like how many CPU it runs on, how much memory it uses on average etc.?
Evan Tahler @evantahler Nov 27 2014 11:17
FYI: I've updated the tutorial for the latest actionhero version https://github.com/evantahler/actionhero-tutorial
Jason Marmon @jtmarmon Dec 01 2014 11:27
I have two separate test files that are run together via mocha
they both actionhero.start() and actionhero.stop at the beginning of their suites, and when run individually, they both pass. however, when i run them together the second suite times out in the beforeAll hook. any ideas?
also the timeout occurs when trying to start actionhero in the second suite, and the done cb in the afterAll hook is called in the actionhero.stop callback :scream:
Evan Tahler @evantahler Dec 01 2014 14:15
@jtmarmon That kind of thing should work great. We use it in the actionhero internal tests https://github.com/evantahler/actionhero/blob/master/test/actions/cacheTest.js
@jtmarmon I've also just split up the actionhero-tutorial tests to give you a simpler example of how this works evantahler/actionhero-tutorial@b779dde
The best way to debug this kind of thing is to turn on logging for the TEST env
usually this means that actionhero is failing to shutdown properly
perhaps you have a middleware that is blocking with a _stop callback that never completes or something
Jason Marmon @jtmarmon Dec 01 2014 14:17
ahhh cool good lead, i'll check it out. thank you :)
Evan Tahler @evantahler Dec 01 2014 14:17
or your after() blocks in mocha don't have the right callbacks set
Jason Marmon @jtmarmon Dec 01 2014 14:22
i see the light already. thanks again :p
Jason Marmon @jtmarmon Dec 01 2014 16:47
am i correct in thinking that specHelpers don't run preProcessors
Evan Tahler @evantahler Dec 01 2014 17:57
Hmm.... If they don't, it's an oversight
I'll check in a bit.
Evan Tahler @evantahler Dec 02 2014 00:18
Yeah, they most certainly do!
make sure you don't have any blocks for connection.type == 'web' or something like that
Jason Marmon @jtmarmon Dec 02 2014 07:46
figured. thanks :)
mfroes @mfroes Dec 04 2014 21:04
hi guys i have been trying to use jquery with actionhero to do ajax calls but even after i do a npm install jquey i cannot use $. or jQuery.
any ideas what i am doing wrong ?
Evan Tahler @evantahler Dec 04 2014 21:09
JQUERY within actionhero... Like on the server?
mfroes @mfroes Dec 04 2014 21:09
yeah
on the action itself
i need to make ajax calls and process it on the action itself
Evan Tahler @evantahler Dec 04 2014 21:10
JQUERY is a browser plugin. Doesn't really work In node. Checkout the "request" paxkage
mfroes @mfroes Dec 04 2014 21:10
so there is a request package that i can use to do the same thing ? is it inside actionhero or is it another package ?
Evan Tahler @evantahler Dec 04 2014 21:12
https://www.npmjs.org/package/request
It's a general node package.
mfroes @mfroes Dec 04 2014 21:12
thanks evan
mfroes @mfroes Dec 04 2014 21:22
thanks evan ... its just as simple to use as jquery
cheers
Jacob Fike @jacobfike Dec 05 2014 10:39
Howdy. I just recently started getting an error in the "after all" block of one of my integration tests. It seems it has something to do with websockets not getting closed properly? The weird thing is that this only happens on my build server, not on any other machine. Any ideas what this means?
1) Blitzkrieg Tunnel Integration Test "after all" hook:
Uncaught TypeError: Cannot read property 'push' of null
at /var/hudson-slave/workspace/Blitzkrieg/blitzkrieg.git/api/node_modules/ws/lib/Receiver.js:463:50
at /var/hudson-slave/workspace/Blitzkrieg/blitzkrieg.git/api/node_modules/ws/lib/Receiver.js:356:7
at /var/hudson-slave/workspace/Blitzkrieg/blitzkrieg.git/api/node_modules/ws/lib/PerMessageDeflate.js:217:5
at afterWrite (_stream_writable.js:325:3)
at onwrite (_stream_writable.js:316:7)
at WritableState.onwrite (_stream_writable.js:103:5)
at afterTransform (_stream_transform.js:99:5)
at TransformState.afterTransform (_stream_transform.js:74:12)
at Zlib.callback (zlib.js:600:5)
Jason Marmon @jtmarmon Dec 05 2014 12:06
i'm sure you've checked but you may want to triple check that you have all your dependencies in your package.json. just my first instinct when you say it's only on a build server
in ws line 463 is if (buffer != null) self.currentMessage.push(buffer); maybe you're not correctly exposing ports on the build server or something
somehow Receiver.prototype.cleanup is getting called because that's the only place it gets set to null in Receiver.js
mfroes @mfroes Dec 07 2014 20:08
is there a way to set the response content-type ?
i try setting it as a response header and get an error on web.js
connection.rawConnection.responseHeaders = {'Content-Type' : 'text/plain; charset=utf-8' };
if( extractHeader(connection, 'Content-Type').match(/json/) ){
^
TypeError: Cannot read property 'match' of null
mfroes @mfroes Dec 07 2014 20:19
looking at the code in web.js i was able to come up with:
connection.rawConnection.responseHeaders.push(['Content-Type', "application/x-mpegurl; charset=utf-8"]);
seems to have worked
Evan Tahler @evantahler Dec 07 2014 20:36
yep, connection.rawConnection.responseHeaders is what you want, but you replaced all of them (there would have been some pre-set ones). Do connection.rawConnection.responseHeaders['Content-Type'] = x
@mfroes ^
Jason Marmon @jtmarmon Dec 08 2014 14:05
@evantahler what do you think about specifying url param types? I have an array of params that becomes a string when only one is passed - it seems like it would make sense to be able to specify that it should be an array. same with specifying and int and so on.
i know in #127 you didn't want to support custom url checking, but specifying type seems like it might be useful in a more general case
mfroes @mfroes Dec 08 2014 16:29
hi evan, just trying to set did not work, but pushing it does
connection.rawConnection.responseHeaders['Content-Type'] = "application/x-mpegurl; charset=utf-8"; --> does not work
connection.rawConnection.responseHeaders.push(['Content-Type', "application/x-mpegurl; charset=utf-8"]); --> this works
mfroes @mfroes Dec 08 2014 16:34
another one: i am trying to get http or https, but the rawconnection doesnt tell me if the connection is encrypted or not. any ideas ?
i am trying to generate the full url, like http://serverurl:port/newAction
mfroes @mfroes Dec 08 2014 20:12
hi. i have been trying to send a Buffer base64 decoded to the client, but i cant seem to make it work
with python and flask it just works in 10 lines or so
i think that the correct way is not to by using
connection.response = new Buffer(key, 'base64');
any ideas?
Evan Tahler @evantahler Dec 08 2014 21:46
@mfroes you will have only boot one HTTP listener, so you can check if it's HTTPs or not from the config. Something like api.config.servers.web.secure I think
and good call on connection header
What type of client are you trying to send the buffer too?
each client type still needs to stringify the body, so your results may varry
and most always JSON
best to convert to string first anyway
@jtmarmon I think in general we should revisit param definitions. Just listing them in an array is OK, and we'll assume eveything is the native type (IE: all web posts are strings). But perhaps we can pass an array of hashes like [{name: userId, type: Number},(name: email, type: string, validator: function()}]
waiting on that PR from someone here :D
mfroes @mfroes Dec 08 2014 21:50
@evantahler the clients are just vlc / mplayer.. i am building a HLS proxy that create live streaming. so the buffer would have to go through without any changes to it. just stream the bytes itself
if i do a new Buffer(key, 'base64').toString(); still fails on getting the decripted value
Jason Marmon @jtmarmon Dec 08 2014 22:51
@evantahler do you mean you know of someone already working on it or you'd like someone to start
mfroes @mfroes Dec 08 2014 23:13
@evantahler the problem with the base64 decoder was that i was decoding the param itself when actionhero does that for me
salles @sallespro Dec 09 2014 09:26
how could it be that calls to api.cache.save do not go thorough redis, even though one can properly see chatRoom and resque worker’s fine ?
salles @sallespro Dec 09 2014 10:26
@evantahler , is it the same to use var redis = api.redis.client; redis.hset(…) and api.cache.save method ?
omichowdhury @omichowdhury Dec 10 2014 05:22
@sallespro Check out the source to api,cache.save
https://github.com/evantahler/actionhero/blob/master/initializers/cache.js#L183
you can see what extra goodies api.cache.save adds - expiration time, lock checkng
it also uses redis.client.set not hset
salles @sallespro Dec 10 2014 14:07
@omichowdhury the original question is to try to figure out why i could not view the keys using redis-commander. i have indeed checked the source and couldn’t find a reason without any error message or so.
in the ah-tutorial, one sees the blog example using node_redis which can be viewed nicely. when i call api.cache.save it returns true and no error. can’t find it though.
Evan Tahler @evantahler Dec 10 2014 15:11
@sallespro try changing the redis DB
IE: select 1 from within redis commander
@jtmarmon waiting for someone to start. There has been some talk, but I don't think anyone ever started
@mfo
@mfroes sorry, actionhero's web server is NOT a streaming webserver. The completion of an action is the end of the connection. We don't support buffers and do our best to stringify them on send. https://github.com/evantahler/actionhero/blob/master/servers/web.js#L80-L92. That said, you can build a new server type to do what you want http://www.actionherojs.com/docs/core/servers.html
Evan Tahler @evantahler Dec 11 2014 17:14
Anyone have any thoughts on this testing bug with the tutorial? evantahler/actionhero-tutorial#10
mfroes @mfroes Dec 11 2014 17:14
Hi there. anyone knows how i can get information of queued tasks with just api.tasks.enqueue ? wanted to know the task and the arguments passed to the tasks. also, i have tried the api.tasks.scheduledAt and it does not exist at the moment. is it an npm issue or a documentation issue ?
@evantahler on mine (also ubuntu) npm test works just fine
mfroes @mfroes Dec 11 2014 17:22
but mine doesnt spit out that many logs or seems to run that much
$ npm test
my_actionhero_project@0.0.1 test /home/froes/workspace/develop/fradio-service-playlist
mocha
actionhero Tests
✓ should have booted into the test env
1 passing (2s)
and thats it
using "actionhero": "9.4.1"
and npm -version 1.4.28
Evan Tahler @evantahler Dec 15 2014 11:30
@mfroes for that kind of thing I would actually look into task.plugins, and in this case jobLock https://github.com/taskrabbit/node-resque/blob/master/lib/plugins/jobLock.js
@mfroes however, you should be able to inspect this kind of thing. Can you post an issue to github?
Also, @mfroes keep in mind if you want to be REALLY safe, you'll need to check if the job is in 3 states: Delayed, Enqueued, and Working. We just added methods to check what the workers are working on: evantahler/actionhero#522
omichowdhury @omichowdhury Dec 15 2014 14:41
@evantahler Yeah I figured that out, we can't set environment variables easily in our production servers, so I couldn't use your ah-newrelic-plugin
had to write a tweaked version of it
otoh I wrote up a quick resque plugin to add newrelic instrumentation to tasks
omichowdhury @omichowdhury Dec 15 2014 15:01
This is it if anyone is interested:
https://gist.github.com/omichowdhury/027c94c46c3d9c40a1c9
Amine Mouafik @kytwb Dec 17 2014 13:01
hey there! anybody using both postgres and mongo with actionhero?
i was thinking of tweaking things so I can have all my models in ./models/
but sequelize (postgres) models within /models/relationals/ and mongoose (mongo) models within /models/documents/
Evan Tahler @evantahler Dec 17 2014 14:08
Heh, I use neither or those.
omichowdhury @omichowdhury Dec 17 2014 14:09
@kytwb We use the mongodb package, with a little sauce to add a promise interface
Used to have mongoskin but it made connecting to a mongo cluster harder than it needed to be in actionhero
Mike Slattery @slattery Dec 17 2014 14:15
@kytwb I use pg with actionhero, but not with sequelize. I assume it would work very well though. I use handtooled SQL called within initializers against the node-postgres-pure client.
Jason Marmon @jtmarmon Dec 17 2014 22:28
anyone have advice on/experience with handling a lot of simultaneously enqueued tasks?
Jason Marmon @jtmarmon Dec 17 2014 23:10
also - is there a reason there isn't a method for inspecting all scheduled tasks for a specific task type (without knowing the arguments passed to it)
omichowdhury @omichowdhury Dec 18 2014 07:14
@jtmarmon anything specific? Our tests load ~20k tasks into the queue. Takes a while to process with only 2 worker boxes (4 instances) but it gets through them. Really important to have your load balancer point to a pool of actionhero servers with no workers to maintain responsiveness under load
Evan Tahler @evantahler Dec 18 2014 09:24
+1 on splitting your "workers" from your "servers".
Are you asking for a method to see how many jobs are delayed in general? If so, open an issue here https://github.com/taskrabbit/node-resque and I'll post it back to actionehr
Amine Mouafik @kytwb Dec 18 2014 09:41
should we make convention to cp plugins config files in ./config/plugins ?
Evan Tahler @evantahler Dec 18 2014 12:51
Only if you need to change the defaults!
Shawn @aimbot Dec 18 2014 15:46
Is there any way to connect to actionheros websocket server (say running ws) without using the compiled client js. The reason being is (if i understand it) if i were to change a setting in the config and a new client side socket js file is generated i now need to update my server side code and wherever my client side code is right? In my case on a phone. Thanks for any answers on the subject!
salles @sallespro Dec 18 2014 16:27
@aimbot yes you can connect. AH uses primus. i am not really sure i understood what you meant about managing the config and the client side socket js.
Shawn @aimbot Dec 18 2014 17:35
actionhero generates the actionheroClient.js files to use on your UI. Is there a way i can use the actionhero server using ws and use the native ws implementation on the client side to talk to eachother instead of having to use the actionhero generated files on the clientside.
Jason Marmon @jtmarmon Dec 19 2014 08:36
@omichowdhury thank you :)
@evantahler taskrabbit/node-resque#59
Mike Slattery @slattery Dec 19 2014 10:17
@aimbot You should be OK if you change settings on the server - the client that gets regenerated should reflect the changes if I read this right: http://www.actionherojs.com/docs/servers/websocket.html#options However, if I'm missing the question I'd bet you could use 'var connection = new WebSocket('ws://example.org:12345/myapp');' against AH. AH does want to see specific verbs and action calls IIRC. The client is a pretty thin wrapper, so you could pull the correct 'grammar' out of that I think.
Evan Tahler @evantahler Dec 19 2014 11:27
@aimbot at the end of the day the actionhero client is a thin wrapper around a specific WS implementation protocol (which you can choose). If you pick this simplest ws protocol under primus (no HTTP fallbacks, etc), you probably can do what you want. However, you will need to match the language and transport semantics defined here (https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js) which include how to connect, how to auth, etc.
That said, I really don't reccomend it :D
Jason Marmon @jtmarmon Dec 19 2014 14:54
Anyone know of a way to prevent periodic tasks from running during tests
Jason Marmon @jtmarmon Dec 19 2014 15:34
if (api.env === 'test' && params.specHelper !== true) { next(); return; } :laughing:
Evan Tahler @evantahler Dec 21 2014 18:08
New documentation section based on a chat @jtmarmon and I were having http://www.actionherojs.com/docs/ops/production-notes.html#topology-example
how to set up a production cluster
to prevent tasks from running in tests, just don't have any workers! (config change)
and if you want to TEST a worker, you can start it up manually: https://github.com/evantahler/actionhero/blob/master/test/core/tasks.js#L218-L229
@jtmarmon ^
Jason Marmon @jtmarmon Dec 21 2014 20:31
thanks so much for the topology diagram @evantahler. definitely helps a lot
Evan Tahler @evantahler Dec 22 2014 10:52
@jtmarmon https://github.com/evantahler/actionhero/pull/526/files
Jason Marmon @jtmarmon Dec 22 2014 16:31
awesome tyvm. i'll just write a utility method that runs a filter to check the task type
Fadi Abu Alnaser @fadiabualnaser Dec 23 2014 05:39
i create an initializers that handle zmq msgs then i start my server as cluster the first worker tell me that the zmq pull socket is open in port xxxx and the second worker tell me that the Address already in use,
any one have the same problem ?
Evan Tahler @evantahler Dec 23 2014 06:52
That's not really how ZMQ works @fadiabualnaser. Here's a good writeup http://stackoverflow.com/questions/24871935/how-to-use-node-js-cluster-with-zeromq-reply-workers
Fadi Abu Alnaser @fadiabualnaser Dec 23 2014 07:29
yes i agree with that answer but if i have 3 workers and every worker will do very heavy process so if just worker 1 listen to zmq msgs and do the heavy process then worker 2 and 3 is useless, what you think ?
Evan Tahler @evantahler Dec 23 2014 17:16
Can't really comment other than "that's not a good ZMQ use case" I guess you could have 1 process listen and then reenaueue to actionhero's task system.
Mike Slattery @slattery Dec 23 2014 18:23
Hi y'all, I have a couple of questions for the chat: 1) Would anyone care to share with us your scenarios for using the AH task system? I'm thinking of using it but I need some ideas to prime the pump. 2) I swear I RTFM but I can't tell if plugin configs get consulted now in order just like the public folders do (which is awesome for me, if it's a bug please don't fix it!), or if I have to mesh the configs together.
Evan Tahler @evantahler Dec 23 2014 22:31
Hey everyone- I'd love to hear some feedback on evantahler/actionhero#523
@slattery if you want some ideas, you can check out anything that uses resque (as that's the backend, and its a very large community). I personally use it all over the place (sending emails, game server computation, stats aggregation, etc). Basically anything your application does that takes longer than 1s could be migrated to a task
I wrote some thoughts on the topic here once http://blog.evantahler.com/blog/on-task-systems.html
you can also extend the whole thing to be a message bus if you want to get really crazy https://github.com/taskrabbit/node-resquebus + http://tech.taskrabbit.com/blog/2013/09/28/resque-bus/
Evan Tahler @evantahler Dec 23 2014 22:36
@slattery regarding plugin configs, I think this is the change you are talking about (merged to master in Aug) evantahler/actionhero#454
Mike Slattery @slattery Dec 24 2014 06:43
@evantahler thanks, great idea re: resque. I remember being very excited about the @PhilWaldmann work. The docs still talk about a post-install config move so I wasn't sure if the configs were consulted for install time info but not run time. ( I'm doing the big shift from 7.x to 9.x. right now)
Jason Marmon @jtmarmon Dec 24 2014 08:21
@evantahler looking at PR #523 i'm thinking it might make sense to enforce some basic quality constraints on the codebase. what do you think about using make for tests and having it also run jshint
Evan Tahler @evantahler Dec 24 2014 08:38
no need to use make, but sure, add in jshint https://github.com/evantahler/actionhero/blob/master/package.json#L61 @jtmarmon
Mike Slattery @slattery Dec 24 2014 09:08
OK, I added a comment to #523, this is great movement forward @neilstuartcraig
Jason Marmon @jtmarmon Dec 24 2014 10:19
216 errors
Evan Tahler @evantahler Dec 25 2014 18:40
I'd love to hear feedback on evantahler/actionhero#528 ( new task system config and underlying worker)
Evan Tahler @evantahler Dec 26 2014 15:56
any more thoughts on evantahler/actionhero#528
omichowdhury @omichowdhury Dec 27 2014 07:58
Looks like a great change!
Jason Marmon @jtmarmon Dec 29 2014 08:41
each task queue is run in series, correct? so if each task can be run in parallel, the most performant queue setup would just be '*' right?
Evan Tahler @evantahler Dec 29 2014 15:10
@jtmarmon depends on the relative priority of your jobs. If you have a high_priority and a low_priority queue, you really want to write ['high', 'low'] to be sure that all jobs in high get worked before any in low
Jason Marmon @jtmarmon Dec 29 2014 16:38
@evantahler so all tasks in queue a of queues [a, b] get run before any tasks in queue b ?
Evan Tahler @evantahler Dec 29 2014 16:38
Yep
Jason Marmon @jtmarmon Dec 29 2014 16:39
ahhh i had no idea. that's interesting. is there no way to execute tasks in parallel then?
Evan Tahler @evantahler Dec 29 2014 18:34
Whoops, sorry. I'm thinking of the new PR. There, parallelism comes from the min/max processor directives. In current master, yes, the queues each spawn a "thread" for parallelism. You can do stuff like ["high,low","high"] I think.
Or sub-arrays.
Its confusing... Hence the new system!
Jason Marmon @jtmarmon Dec 30 2014 20:31
my head hurts. they don't actually spawn new threads right? nor new processes, they just don't run in series, correct?
Evan Tahler @evantahler Dec 30 2014 21:20
Correct, no new threads or processes... Just async processors
Jason Marmon @jtmarmon Dec 31 2014 10:21
gocha
Jason Marmon @jtmarmon Dec 31 2014 10:33
@evantahler what do you think about promise bindings for api methods
Jason Marmon @jtmarmon Dec 31 2014 10:39
could do something like
delDelayed: function(q, taskName, args, callback){
if (typeof callback === 'function') {
api.resque.queue.delDelayed(q, taskName, args, callback);
} else {
return Q.denodeify(api.resque.queue.delDelayed.bind(api.resque.queue))(q, taskName, args);
}
},
omichowdhury @omichowdhury Dec 31 2014 11:48
@jtmarmon We have an initializer that runs through the api object and adds promise versions of the functions e.g. api.tasks.enqueue.q(...)
Jason Marmon @jtmarmon Dec 31 2014 12:45
ah smart i think i'll do that, thanks. though having that functionality embedded would be convenient
omichowdhury @omichowdhury Dec 31 2014 13:03
I think its best to leave libraries/frameworks un-opinionated when it comes to solving the callback problem
Shawn @aimbot Dec 31 2014 23:48
Question, is anyone having issues with websocket reconnection after manually shutting down the node server its connected to. Im running a stock websocket.js config file with the exception of my clientUrl and im not seeing the client reconnection attempts failing in the console. I also tried defining all of the strategies on as well as min and max for the reconnect config block. I understand this is about primus but i thought I would just ask.
Evan Tahler @evantahler Jan 01 2015 01:33
Hmm. Can you file an issue for that please?
@omichowdhury can you share that initilizer? Maybe make a plugin?
Evan Tahler @evantahler Jan 01 2015 15:26
Issue filed evantahler/actionhero#533
Evan Tahler @evantahler Jan 01 2015 19:18
@aimbot evantahler/actionhero#534
Shawn @aimbot Jan 02 2015 00:30
@evantahler Excellent, works perfectly. Thanks for the quick turnaround on that one.
Jason Marmon @jtmarmon Jan 02 2015 09:29
anyone know why an actionhero server might not startup? my initializers don't seem to be the problem as the both successfully call next()
edit: jk. just bad env vars
Evan Tahler @evantahler Jan 02 2015 22:07
In actionhero v10.x.x, there will be an overhaul of the init system. Note how the structure of initializers change. I think this is clearer and more flexible. You can finally determine load order, including before the core actionhero init system. evantahler/actionhero#535
What else is on the v10 roadmap? Everything you see here ( https://github.com/evantahler/actionhero/compare/v9.4.1...master ) + some more hooks into the chat system (like events on SAY, etc)
Jason Marmon @jtmarmon Jan 03 2015 13:53
ah nice - loading before the core init system is definitely a plus
Chad Robinson @crrobinson14 Jan 03 2015 18:53
@evantahler We found a workaround for loading NewRelic early enough to instrument MySQL - we load it from within config/mysql.js. For Redis, we tracked the issue down to a facile detection method in NewRelic itself - ActionHero's "config/redis.js" throws it off. The same trick can't be used there because ActionHero itself includes a file with this name, and it's loaded early. But we view this as more of a NewRelic issue, so we've filed a support request for it on their forum. Including the link here in case anybody else has hit this. https://discuss.newrelic.com/t/uninstrumented-module-detection/14527
We're still looking forward to being able to control the order-of-operations of various things in the init process - I can see a LOT of areas where that would be useful. But at least for NewRelic, I don't see the need to change anything in core for that.
The say() hooks will be much appreciated. We were looking at submitting a merge request for those - have you already started working on them?
Evan Tahler @evantahler Jan 03 2015 18:56
@crrobinson14 good to heat about the newRelic updates! I think evantahler/actionhero#535 is almost ready to go (initializer load order). I haven't started the SAY hooks yet.
Chad Robinson @crrobinson14 Jan 03 2015 19:12
What's your position on parallel/series? IMO this mechanism is most useful for two use-cases: persisting messages to a database (without having to run some agent that subscribes to every room) and doing spam/banned-user/content filter blocking (like stripping naughty characters). A parallel call is probably acceptable for persisting the messages, but not for the other use-cases.
Chad Robinson @crrobinson14 Jan 03 2015 21:36
Anybody have any thoughts on unit-testing WebSockets components, like chat room behavior?
I'm working now on something that will execute an action that should post updates to a chat room. Basically, it's a moderation use-case. The moderator flags/deletes an item, and a 'say' is broadcast to everybody in that room to nuke the message.
So the test case needs to execute the deleteMessage action and then wait for a chat room message to be fired. It's sort of working but super awkward if you want to stamp out 20 more of the same pattern.
Evan Tahler @evantahler Jan 04 2015 09:04
There are tests for the chat system here using the specHelper https://github.com/evantahler/actionhero/blob/master/test/core/actionCluster.js you can see examples how to look for messages received.
Evan Tahler @evantahler Jan 04 2015 13:13
@crrobinson14 I'll move the chat callbacks to series. I'm convinced!
Evan Tahler @evantahler Jan 04 2015 19:42
And here's the updated chat system with new hooks for say. There are a lot of changes here... tell me what you think! evantahler/actionhero#537
@crrobinson14 ^
Evan Tahler @evantahler Jan 04 2015 21:02
Please take a look at the PR above. Assuming it gets merged in, here's the whole changelog for actionhero v11 https://gist.github.com/evantahler/f38ee2834d79f52f6996
Chad Robinson @crrobinson14 Jan 04 2015 21:04
Wow, that was fast. I hadn't even had a chance to look at it myself!~
It's fairly late here -I'll definitely look at it first thing in the morning.
Evan Tahler @evantahler Jan 04 2015 21:05
Whoops! we are on v10. I got ahead of myself
no rush! I had a productive day :D
Chad Robinson @crrobinson14 Jan 04 2015 21:09
Apparently! I spent the weekend writing unit tests. Thanks for your tips earlier on how to trap chat room messages that follow from actions. Just curious, there's a lot of setTimeout(..., 100) checks in the cluster tests. I assume this is to allow time for the messages to "settle"?
Evan Tahler @evantahler Jan 04 2015 21:13
If i recall correctly, I think those are mostly for the FAKEREDIS implemnetation of the tests. If you check the test matrix https://travis-ci.org/evantahler/actionhero we test various node versions and redis adaptors
the in-process in-memory one (fakeredis) does some weird stuff with callback order + pub-sub sadly.
which I guess makes sense... being in-process and all. I think they need more setImmediate() in their code... but I haven't gotten into the guts yet
Chad Robinson @crrobinson14 Jan 05 2015 04:09
@evantahler Love the new chat patterns.
Chad Robinson @crrobinson14 Jan 05 2015 04:15
Just brainstorming re: missingParamsCheck... Wouldn't it make more sense to do something like this declaratively in the action meta-data? A structure like this would be easy to parse, very flexible, and more granular that mixing in-action and system configs. This is very similar to what Swagger does:
inputs: {
'required': ['name', 'photo'],
'optional': ['location']
},
becomes:
inputs: [{
name: 'name',
source: 'query', // query|body|...
required: true,
default: null, // null|value. To get 'undefined', omit the default.
}, {
name: 'photo',
source: 'query',
required: true,
default: null,
}, {
name: 'location',
source: 'query'
}],
Oops, that doesn't format well. Sorry. The point is, rather than iterating two collections of inputs (required and optional) and storing other behavior config elsewhere (system config for how to deal with missing parameters), you just parse every option (get/post), then iterate a single collection of expected inputs.
This lets you be super-explicit and also very flexible. For instance, you could easily write a middleware that adds support for inputs coming from cookies. Just add a request pre-processor that iterates the action template for parameter defs of source 'cookie', and parse the request cookie to match them up.
Chad Robinson @crrobinson14 Jan 05 2015 07:34
FYI I'm working on a plugin to generate "API Blueprint" compatible docs from the action templates.
Mike Slattery @slattery Jan 05 2015 08:50
I am "+1"ing this really hard re:promise sweep... @omichowdhury can you share that initilizer? Maybe make a plugin?
Evan Tahler @evantahler Jan 05 2015 09:09
@crrobinson14 The new release would be a GREAT place to upgrade the params to something like you have. I would also love to see something more like this: evantahler/actionhero#538 Please put your thoughts in the PR
The source thing is a little tricky when you have a cross-transport API. Would you have that per-srever?
I think I would hold off on that part until after the switch
(this is why I've had a swagger branch for AH lying around for almsot a year that I can't quite make fit)
Mike Slattery @slattery Jan 05 2015 11:00
@evantahler Hi Evan, for actionhero v10.x.x , I imagine plugin load order will be taken care of by the priority metadata for initializers within them, is that true or will there be another factor? I am loving what I see in that readme.
omichowdhury @omichowdhury Jan 05 2015 13:03
@slattery Haha it's actually not some magical function - we have a map in our code, it's definitely klugey but it works and I haven't had to update it in a long time. Mostly because the application initializers we define have promise interfaces any way
{
parent: api.mongoClient,
methods: ["connect"]
}, {
parent: api.cache,
methods: ["load", "save", "destroy"]
}, {
parent: api.tasks,
methods: ["enqueue", "enqueueIn"]
}
apparently we only need to use those 5 functions in AH's api :smile: - a sign of a well designed API
var Q = require("q");
exports.patch = function () {
var args = Array.prototype.slice.call(arguments);
args.forEach(function (obj) {
obj.methods.forEach(function (method) {
obj.parent[method].q = Q.nbind(obj.parent[method], obj.parent)
})
});
}
but here's the code for completeness
omichowdhury @omichowdhury Jan 05 2015 13:08
@jtmarmon ^
Evan Tahler @evantahler Jan 05 2015 18:55
@slattery Yep! initializers from plugins, core, and the local project will all use the new loadPriority, startPriority, etc
@slattery et al, take a look at the priorities I assigned to the core initializers too. I made 1 -> 1000 for core, with the assumption that plugins and the local project would be in the 1xxx range. That said, there is room to be below internal levels too... like there is nothing at 0 -> 100
@omichowdhury one of these days we need to get into a better documentation pattern for actionhero... documenting the exposed methods in-line. Then, you could also detect those methods automatically to Q wrap them :D
Mike Slattery @slattery Jan 06 2015 07:54
@omichowdhury Thank you. I was happy to see how straightforward it is!
Mike Slattery @slattery Jan 06 2015 10:19
@evantahler the universal application of priority is really helpful.
Chad Robinson @crrobinson14 Jan 06 2015 12:03
@evantahler Do you have a recommended workflow for contributing PRs? There are breaking changes in 10.x (mostly the initializer _start() -> start() stuff). We want those things... but they aren't published to NPM yet so we can't upgrade our projects. (I suppose we could just use the @Github method?) Meanwhile, there have been changes to configLoader, so I can't push a clean pull request for the multi-config support without updating. That is, I can SEND it, but I can't TEST it easily in my project without upgrading it...
I suppose one option is to just make a "sample" project instead, just against the new code... But then we'd like to use this new config optoin. :)
Chad Robinson @crrobinson14 Jan 06 2015 14:19
@evantahler PR evantahler/actionhero#541 sent!
Evan Tahler @evantahler Jan 06 2015 22:56
If things get really complex in the future the proper workflow is to PR/merge against a new "release" branch.
We can start that with v11 if folks want it, it just hasn't come up yet.
Chad Robinson @crrobinson14 Jan 07 2015 04:36
That's probably a good idea, but it looks like it wasn't as big of an issue as I thought. The initializer lifecycle callbacks was the only breaking change, and it only took a few minutes to convert them. I know there are plenty of people who disagree with me, but I've never been afraid of breaking changes. I think more software cruft and missed opportunities have come from that fear than anything else. I always happily pay that as the cost of innovation.
Jason Marmon @jtmarmon Jan 07 2015 06:13
@omichowdhury thanks for that. looks great :)
Jason Marmon @jtmarmon Jan 07 2015 08:43
i know initializer load order is going to be a thing in 10.x.x - is there a workaround in the meantime? I'm doing some cleanup by applying @omichowdhury's method to some additional callback-based apis and am getting an error because they haven't yet loaded by that initializer
omichowdhury @omichowdhury Jan 07 2015 08:53
@jtmarmon IIRC initializers are loaded in alphabetical order
Jason Marmon @jtmarmon Jan 07 2015 08:54
ah
intializers/z_promiseify.js
hahahaha
Evan Tahler @evantahler Jan 07 2015 12:20
Yeah, I've got a few of those... intializers/aaa_loader.js... that's why we now have evantahler/actionhero#535 :D
Jason Marmon @jtmarmon Jan 07 2015 14:22
2 PRs fresh out of the oven for ya @evantahler
#543 #542
Jason Marmon @jtmarmon Jan 09 2015 07:02
@evantahler is the scheduledAt method on npm?
Jason Marmon @jtmarmon Jan 09 2015 09:58
also, if I have no queues enabled, then I enqueue a task, it will still get pushed to redis, so I can still check it was enqueued by the count argument from api.tasks.del correct?
Jason Marmon @jtmarmon Jan 09 2015 10:30
because if you can that means my tests are working, which would be ridiculous
also is it just me or does "highest numerical version" (from the docs) mean the opposite of this: https://github.com/evantahler/actionhero/blob/master/test/core/api.js#L117
Evan Tahler @evantahler Jan 09 2015 13:21
@jtmarmon I cleared up the name of the test for you evantahler/actionhero@3c0efba It does pick the highest version, per https://github.com/evantahler/actionhero/blob/master/test/core/api.js#L134-L139
and yes, you can always enqueue. nobody will work it, but it will be stored
if you want a redis UI, check out https://github.com/joeferner/redis-commander you can see the data in there (you need to be using real redis obviously)
Jason Marmon @jtmarmon Jan 09 2015 14:26
ah got it. and this looks cool checking it out now
Chad Robinson @crrobinson14 Jan 09 2015 19:47
Redis Desktop Manager is also really nice if you need to poke around nodes. http://redisdesktop.com/
@evantahler Did you see our PR541? Not really in a rush merge-wise, but would love to know at least if it's just "not gonna happen" so we can think about alternative methods.
Evan Tahler @evantahler Jan 09 2015 21:57
No not yet. I'll try to check all the PRs this weekend
Evan Tahler @evantahler Jan 10 2015 17:13
Anyone here use mongo? This example is really old... can someone update it please? http://www.actionherojs.com/docs/examples/initialzers/mongo.html
salles @sallespro Jan 10 2015 17:18
@evantahler this is a bare minimum working example.
var mongoPackage = require('mongodb');
var async = require('async');
var mongo = function (api, next) {
api.mongo = {};
api.mongo.client = {};
api.mongo.enable = api.config.mongo.enable;
api.mongo.client = mongoPackage.MongoClient;
api.log("configuring MongoDB "+api.config.mongo.enable, "notice");
if (api.config.mongo.enable == true) {
var url = 'mongodb://'+api.config.mongo.host+':'+api.config.mongo.port+'/'+api.config.mongo.db;
api.mongo.client.connect(url, function(err, db) {
if(err) {
api.log(err+"error in mongoDB connection", "notice");
next();
} else {
api.log("mongoDB connection ok ", "notice");
api.mongo.db = db;
next();
}
});
}
}
/////////////////////////////////////////////////////////////////////
// exports
exports.mongo = mongo;
Evan Tahler @evantahler Jan 10 2015 17:20
That's perfect @sallespro!
please pr that into the gh-pages branch!
Chad Robinson @crrobinson14 Jan 10 2015 18:25
We use Mongo but not yet with AH. We're using Sequelizer+MySQL for that. We had actually planned on posting our initializer as a Gist but it's not quite ready. We're wiping/reloading the database on every boot, and want to support "migrations" before using it as an example.
Thanks for merging the config PR, I'll add something to gh-pages shortly.
salles @sallespro Jan 10 2015 18:29
there it goes evantahler/actionhero#548
Evan Tahler @evantahler Jan 10 2015 20:11
@crrobinson14 I made this a while ago for sequelize+actionhero https://www.npmjs.com/package/ah-sequelize-plugin
For refrence
Evan Tahler @evantahler Jan 10 2015 20:19
Thanks @sallespro!
I like having an active community :D
OK everyone, here's the last major update to actionhero v10: The long-awaited param validation/defaults/formatting update!
evantahler/actionhero#549
here's the archetypical example:
exports.sleepTest = {
name: 'sleepTest',
description: 'I will sleep and then return',
inputs: {
sleepDuration: {
required: true,
formatter: function(n){ return parseInt(n); },
default: function(){ return 1000; }
validator: function(n){
if(n < 1000){ return 'sleepDuration should be longer than 1 second'; }
else{ return true; }
}
}
},
run: function(api, connection, next){
setTimeout(function(){
next(connection, true);
}, connection.params.sleepDuration)
})
}
This still works in concert with evantahler/actionhero#514 @chimmelb
Evan Tahler @evantahler Jan 10 2015 20:25
(it's used to tell what "present" means for required now => https://github.com/evantahler/actionhero/blob/master/initializers/actionProcessor.js#L216-L219)
@/all So other than some minor cleanup and updating the docs, I think that v10 is more-or-less ready to go out! Let me know your thoughts!
Evan Tahler @evantahler Jan 10 2015 20:30
again, I'm keeping the the v10 changelog here https://gist.github.com/evantahler/f38ee2834d79f52f6996
Evan Tahler @evantahler Jan 10 2015 22:19
much prettier https://cloud.githubusercontent.com/assets/303226/5694496/dd1ca4ce-9913-11e4-93d9-9dfa1e6875f1.png
Jason Marmon @jtmarmon Jan 10 2015 22:55
so much easier on the eyes :heart_eyes:
Sebastian Dechant @S3bb1 Jan 11 2015 02:59
Nice theme @evantahler ! Looks better than before!
Mike Slattery @slattery Jan 11 2015 07:10
I am excited for v10!
Mike Slattery @slattery Jan 11 2015 07:16
@evantahler this is OT, but I would love to see a blog article (or two) that talks about how you manage this project. AH Community, I'd also be interested to see how you all manage your AH projects/environments/migrations! This might be more of a mailing list thing so I'll post it there.
Evan Tahler @evantahler Jan 11 2015 16:43
Thanks @slattery! Frankly, I probably could be doing a better job with true community management. I mean... we've never even had a meetup (as far as I know). I think I've got a good handle on the online parts, but we really should take it to the next level. Anyone have any suggestions?
I'll write some blog posts for you either way :D
Evan Tahler @evantahler Jan 11 2015 16:54
@/all there are a few issues in the v10 milestone about updating some of the related projects and documentation (like the tutorial). Does anyone have time to work on them? I won't hold up the release for them, but it would be nice to get them out the door soon after the release https://github.com/evantahler/actionhero/milestones/v10.0.0
Jason Marmon @jtmarmon Jan 11 2015 18:56
@evantahler I know it's split between nyc and sf so i think we should have a meetup in kansas
Evan Tahler @evantahler Jan 11 2015 19:21
Ahjs-ks
Ha
Jason Marmon @jtmarmon Jan 11 2015 19:37
lolol i can see it happening. will there be reimbursements?
Evan Tahler @evantahler Jan 11 2015 19:49
sure, all attendees get a free github star.
BTW, v10.0.0 is up
Jason Marmon @jtmarmon Jan 11 2015 19:49
you're a generous based maintainer. and yay mazel tov
now i can rename z_promisify
Jason Marmon @jtmarmon Jan 11 2015 23:55
what's the graceful way of shutting down a task-processing box during deployments? or is that something handled in the actionhero teardown
Evan Tahler @evantahler Jan 12 2015 09:21
Should already be handled in the stop steps https://github.com/evantahler/actionhero/blob/master/initializers/resque.js#L132-L141
Jason Marmon @jtmarmon Jan 12 2015 12:27
ah cool
Chad Robinson @crrobinson14 Jan 13 2015 11:06
@evantahler LOVE the new params structure - much more declarative, and I can expose things like api.models.MYOBJECT.validate from the database to re-use there, so it's very easy to read.
One question tho, did the pipeline for how these requests get processed change? I used to have a piece of middleware that required a valid user session before creating, say, a user profile object. It seems like the validators now run before the middleware (or maybe I just need my session validator at the right level?) My unit test that has an invalid session and a missing parameter used to fail on the invalid session first, and stop there. Now it checks for (and throws) an error on the required parameter, too.
Evan Tahler @evantahler Jan 13 2015 13:46
@crrobinson14 we should be running the validators/formatters after the middleware https://github.com/evantahler/actionhero/blob/master/initializers/actionProcessor.js#L290-L293. Please file a bug if that's not the case!
Chad Robinson @crrobinson14 Jan 13 2015 15:43
@evantahler I'm not sure whether this was intentional or not, but it looks like everything seems to happen around priority 1000? Because I just changed my session middleware to 250 and it started running at the right time. I can try to replicate this if you think it's imoprtant, but we're good to go for now.
Evan Tahler @evantahler Jan 13 2015 15:44
I think you got bit by evantahler/actionhero@45feaf9
upgrade to 10.0.3 and give it a shot
Chad Robinson @crrobinson14 Jan 13 2015 16:36
Ah, maybe so. We're on 10.0.2 now. I'll test and confirm back here.
Question for you - what workflow would you recommend for chatroom's sanitize/generate member details routines? Like, if you actually want to get a person's name, avatar, or whatever... Those calls are blocking right now, so how would you go out to the database or cache to get those dtails?
Are these things that should be looked up when the user connects, instead, and stored on the connection object ahead of time? If so, how do you stop the user from joining a room so fast that the lookup hasn't completed yet?
My use case is: populate each chat room member's name and avatar.
Evan Tahler @evantahler Jan 13 2015 17:07
That's an application design question really. In general though, I would say that you should have a "setup" action which would populate this information onto the connection object. Then, you would have middleware for future actions that blocks unless this data is set. You could also check that connection.userData !== undefined in both action middleware and chat middleware
Chad Robinson @crrobinson14 Jan 13 2015 17:58
I guess what I was really asking was philosophically, how would the framework be best used: using the new async mechanism in the join callback (which I see occurs before generateMemberDetails) and then... what? Stuffing it into an arbitrary key in connection for generateMemberDetails to then come bring into the final key?
That flow of operations would appear to do what I want and it's certainly cleaner than trying to do something after-the-fact and handling it through an app-specific broadcast message...
Evan Tahler @evantahler Jan 13 2015 23:51
I guess it depends on how much data you are talking about @crrobinson14. I don't see anything wrong with keeping a small connection.userData = { name: '', email: ''}, and I do it all the time . That said, if you are keeping a lot of data, you may want so store it in a redis/memecache sidecache and just note on the connection that the user has been 'hydrated' for refrence by others
I think I understand what you asking, but I might be missing it
Chad Robinson @crrobinson14 Jan 14 2015 08:41
I thought about using Redis but the problem is the generateMemberDetails/sanitize pair are sync. So you can't make an async call to Redis to get it back and use it there.
I just discovered today that for a WebSocket connection, connection is regnerated on every request. If you want to store data between actions it needs to be on rawConnection. I'm sure this is documented somewhere but wanted to say it out loud in case anybody wanted to know.
@evantahler I went through the breaking changes from 10.x but must have missed something. None of my periodic tasks are running any more. I double-checked against the tasks shipped with ActionHero as examples and they look correct - is there something specific I need to enable to get them to run again?
To be clear, they worked in 9.x so I had whatever config was appropriate for that.
Evan Tahler @evantahler Jan 14 2015 08:47
If anyone has any design chops, I think a simpler homepage for actionherojs.com that does something like this evantahler/actionhero#560 would be very useful
@crrobinson14 a new WS connection is created each time you load a page, but not for every request on the same page... is that what you are seeing?
Chad Robinson @crrobinson14 Jan 14 2015 08:50
I'm good friends with a talented designer- I'll ask if he has any bandwidth.
Sorry for the thing above - disregard. I had misconfigured the min/max workers control on that specific node. :(
My bad.
Regarding the WS thing, what I see is that if I set connection.value=1, in the next action callback, connection.value is now undefined. But if I set connection.rawConnection.value=1, in the next action connection.rawConnection.value === 1
Obviously you don't expect to have this stuff persist across Web calls. This is just for WebSockets, to cache session data once it's already looked up. There's no reason to hit Redis/MySQL to look up a user ID once you already know it. I'm not sure if that's the best place to store it, but after I do the auth cycle I've been putting it in connection.rawConnection.session
Evan Tahler @evantahler Jan 14 2015 08:53
Sorry, yes. Save data to rawConnection when within actions and middleware
that eventually bubbles up to connection outside of that context
oh, or you can use originnialConnection
https://github.com/evantahler/actionhero/blob/master/initializers/actionProcessor.js#L27
that's much better
The reason for that is that in the actionProcessor we want to lock the state of the connection in place so that you can change params etc on the connection quickly without upsetting an action already in place
There's probably something better we can do here... list any thoughts in a GH issue!
Lets think about this here evantahler/actionhero#561
Chad Robinson @crrobinson14 Jan 14 2015 08:58
Got it, that makes sense.
rawConnection, that is, makes perfect sense to me. I don't touch originalconnection - don't really understand its purpose. I may not be the best voice playing devil's advocate about its value. :)
You could nuke it and I wouldn't notice!
So my one outstanding question is, since generateMemberDetails is sync, but the joinCallback is async... Right now I'm looking up the user in the joincallback to get their name and photo. I stuff that into rawConnection, and then in generateMemberDetails I pull it back out and give it to AH to store in Redis.
But that sort of begs the question about the value of generateMemberDetails in the first place. Is this extra layer necessary? Perhaps it could simply be part of the contract that anything done in the join callback could write to connection.memberDetails or something, and know that this would be saved?
It's not really that big of a deal, I'm just fishing for the ideal pattern here
Evan Tahler @evantahler Jan 14 2015 10:25
sanitizeMemberDetails and generateMemberDetails are really more about the roomStatus() method. When clients ask "who is in the room with me". Those methods are overlaod-able so you could choose to save added info (image, email, etc) in the redis block about the room. You will note that only some properties of the connection (which is already expected to be "Set up") are saved and returned.
Chad Robinson @crrobinson14 Jan 14 2015 10:53
I do note that. But generateMemberDetails is sync. How would you obtain the user's image or email if you had to take the connection's fingerprint and go get more information about it?
Evan Tahler @evantahler Jan 14 2015 21:01
oh! perhaps the main confusing point is when clients are able to join the room. I'm guessing that you wouldn't let the connection in the room without having all of that data populated onto the connection already (middleware would block it... or load it). So by the time the connection is actually joined into the room, you can be sure all the data is set on the connection.
Chad Robinson @crrobinson14 Jan 15 2015 08:29
Fair enough.
Chad Robinson @crrobinson14 Jan 15 2015 10:13
@evantahler We've just noticed that if you call client.action() when no websocket is connected, the callback will receive (err, data) as parameters. If the websocket was connected, you receive (data, undefined). We were going to submit a PR to "fix" this so they're consistent - but wanted to confirm first that it wasn't deliberate?
Evan Tahler @evantahler Jan 15 2015 10:16
I take it you are looking at the discrepency between the ActionheroClient.prototype.actionWeb and ActionheroClient.prototype.actionWebSocket methods, yeah? https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L152-L179
yes please!
Chad Robinson @crrobinson14 Jan 15 2015 10:17
Just to clarify, not in the params they're called with, but specifically the difference in how they call their callbacks here https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L158 and here https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L118
Evan Tahler @evantahler Jan 15 2015 10:17
I think the trick would be to mush the HTTP errors into an object to match the WS client
Chad Robinson @crrobinson14 Jan 15 2015 10:17
What's your preference here?
Ok, we can do that.
Evan Tahler @evantahler Jan 15 2015 10:17
or should the WS client return (error, data)
haha
I leave it up to you!
Chad Robinson @crrobinson14 Jan 15 2015 10:17
<shrug> I was going to do err,data just because that's so common
Evan Tahler @evantahler Jan 15 2015 10:17
(error, data) is more common
go for it!
Chad Robinson @crrobinson14 Jan 15 2015 10:18
kk
Evan Tahler @evantahler Jan 15 2015 10:18
that is a breaking change though
Chad Robinson @crrobinson14 Jan 15 2015 10:18
Hmmm, yes
Evan Tahler @evantahler Jan 15 2015 10:18
so we'll need to bump some versions
Chad Robinson @crrobinson14 Jan 15 2015 10:18
We could gate it on a config setting but then the code base gets crufty.
Evan Tahler @evantahler Jan 15 2015 10:19
do it in 2 phases then: 1) make the HTTP one match the WS one (with callback(data))
then phase 2 is the breaking change we'll save for v11 with callback(err, data)
Chad Robinson @crrobinson14 Jan 15 2015 10:20
OK so just https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L158-L160 for this PR
Evan Tahler @evantahler Jan 15 2015 10:54
I think so!
Chad Robinson @crrobinson14 Jan 15 2015 11:04
OK, #562 sent, let me know if you want it done a different way. If you want it to be more sophisticated, callback.length returns the parameter count for a function. We could tolerate both use-cases by passing (err,data) for callbacks that accept two params, and (data) for callbacks that accept one. But in my PERSONAL opinion I'm not sure that's justified.
Evan Tahler @evantahler Jan 19 2015 21:58
What are your thoughts on evantahler/actionhero#566 I tried to come up with a simpler landing page https://cloud.githubusercontent.com/assets/303226/5812752/fc177a7a-a025-11e4-8c59-a0939c662ee3.png
omichowdhury @omichowdhury Jan 20 2015 07:29
@evantahler Very nice
Jason Marmon @jtmarmon Jan 21 2015 17:52
@evantahler any thoughts on io.js
Jason Marmon @jtmarmon Jan 21 2015 18:12
also, still a bit uncertain about queues in 9.x.x (haven't upgraded to 10.x.x just yet) - if I throw two tasks into queue 'x', will they be processed simultaneously, or in series? if the former, is the only point of queues in 9.x.x to manage priorities when there is CPU availability?
Evan Tahler @evantahler Jan 21 2015 18:49
On purpose, I have no opinion on iojs at this time :)
But yes, in all cases queues are for priority Managment.
Jason Marmon @jtmarmon Jan 21 2015 18:50
got it and lol i'm just dreading when the node ecosystem starts looks like the python one
2.x vs 3.x, es5 vs es6
forever
:scream:
Chad Robinson @crrobinson14 Jan 22 2015 11:25
@jtmarmon We trialed io.js here and AH ran fine in it - no changes at least for what we're doing. We ended up deciding to stick with NodeJS for the project we're launching soon just to be on the "safe" side, but not for any justified reason.
Evan Tahler @evantahler Jan 22 2015 14:11
Same here... as far as I can tell, it works. When Travis has it, I'll add it to the test suite. I have no plans of migrating to --harmony features yet (for compatibility)... but who knows what the state of the world will be in a year or so
Jason Marmon @jtmarmon Jan 23 2015 06:27
honestly all I want is some string interpolation
Chad Robinson @crrobinson14 Jan 23 2015 22:06
Love the way the guts of this thing are put together. The system uses itself to add its own core features - initializers concept used to provide actionProcessors and chatRoom functionality is elegant. Nice!
Jason Marmon @jtmarmon Jan 24 2015 03:16
@evantahler any idea why my tasks just aren't getting queued into redis? "resque:queue:default" has just one value and it's a recurring task from an old version of my api that no longer exists
Chad Robinson @crrobinson14 Jan 24 2015 09:16
@jtmarmon Are you on AH 10.x? This config block is working for me - you have to set min and max task processors in addition to the queues to run
exports.default = {
tasks: function(api) {
return {
scheduler: true, // Run a scheduler on this node
queues: [''], // One worker on the queue. ['high,low'] would be one worker on two queues.
timeout: 5000, // Sleep 5s between job checks
redis: api.config.redis, // The Redis server to query
minTaskProcessors: 1, // The number of task processors for this node to spawn
maxTaskProcessors: 1, // How many tasks to run in parallel
checkTimeout: 500, // How often to check to start new tasks
maxEventLoopDelay: 5 // *TODO: What does this do?
}
}
};
(Can Gitter handle code formatting in some way?)
@evantahler So I'm working on this middleware enhancement PR and found what I THINK is a bug - or maybe I'm just not understanding your purpose?
addPreProcessor stores middleware in a hash where the priority is the key. The element is an array of preprocessors at that priority.
Right here you sort them before you run them. And what you're sorting is an array you extracted of the priorities, not the middlewares themselves.
https://github.com/evantahler/actionhero/blob/decea34c1e508b60faf850751171cf3c42b27c5a/initializers/actionProcessor.js#L127
But... If you console.log() this array produced, check this out
console.log(priorities) => [ '100' ]
It's an array of strings... So .sort() is sorting alpabetically, not numerically.
Is there some purpose this is serving, or is it a mistake I should fix in this PR?
Chad Robinson @crrobinson14 Jan 24 2015 11:18
PR evantahler/actionhero#570 filed for the action middleware. Comments welcome.
Evan Tahler @evantahler Jan 24 2015 11:53
You can use github - markdown on gitter so like
I used "```" to start this code block
@jtmarmon lets see you config, maybe we can help
Crap. @crrobinson14 Yes, that's a bug. The same as this one evantahler/actionhero@45feaf9
Please send a PR just for that :D
Jason Marmon @jtmarmon Jan 24 2015 13:02
@evantahler config for tasks? i just have var queues = process.env.IS_TASK_BOX === 'true' ? ['default'] : []; so that queueing is only enabled on particular instances. but shouldn't the tasks get queued into redis even if they aren't being processed?
oh and I'm still on 9.4.1 - haven't gotten a chance to upgrade
Chad Robinson @crrobinson14 Jan 24 2015 14:18
@evantahler OK will send a separate PR for it. I can see actually that some work was done already to try to mitigate it - when addPreProcessor() is called, it's casting to Number there. But since JS object keys are always treated as strings (until we have ES6), JS is casting it right back when they're extracted. It's a simple fix.
Evan Tahler @evantahler Jan 24 2015 17:15
Thanks @crrobinson14 !
@jtmarmon yeah, they should get sent into redis either way
you can use grunt console locally and check if your enqueue methods are working
perhaps the nodes aren't really sharing the same redis instance?
Jason Marmon @jtmarmon Jan 24 2015 18:36
yeah it's probably some configuration thing. chef is a PITA to debug
Chad Robinson @crrobinson14 Jan 27 2015 05:19
@evantahler We're tracking down some issues when using actionheroClient.js. We've found two problems with it and would like some advice on how to proceed - should we file PRs to change this, is it something you want to look at, etc.?
If the WebSocket is up, action parameters are serialized fine. If it is not, actionWeb doesn't serialize params and always makes a GET request. You can end up with things like http://mybox.mydomain.com/api?&user=[object%20Object]&action=createUser&
There is a race condition in the WebSocket message handling related to actions and callbacks. The use of a message count to sync these up is the issue. If actions are performed at around the same time that the server is sending down messages of its own, the client and server side messageCounts can get out of sync, so the response comes down with the wrong messageCount. There is a spot in the server code where messageCount is set by the server... but on the client it looks like it always trusts its internal counter. It doesn't pass the count into the message itself, so the server doesn't really know what # the client is on, reliably.
Chad Robinson @crrobinson14 Jan 27 2015 05:26
I believe the correct fixes are to a) make all Web-based action requests as POSTS, to handle length limits, and JSON.parse/encodeURIParams the values, and b) to adjust messageCount to be more of a messageId that the client ALWAYS sets, and the server ALWAYS obeys. If it's not set (non-actionheroClient.js request) the server can generate and use its own, but if the client sets it, the server should remember it and pass it back through intact in a response.
Chad Robinson @crrobinson14 Jan 27 2015 07:33
Also, as a stretch goal, there is a routes config block. It may be worth sending a parsed/trimmed version down when actionheroClient is generated (or as some internal API request?). That could provide a mapping of method:action pairs so the client would know how to route an action. If you define an action as only callable via PUT or POST, for instance, if the WebSocket is down and you have queryRouting set to 'false', actionheroClient.js is basically unusuable.
Chad Robinson @crrobinson14 Jan 27 2015 09:14
A little more debugging seems to indicate that the problem is easiest to replicate if you do a room join just before the WebSocket is connected. It queues this, but messageCount is NaN at the time because 'open' hasn't been called so messageCount is off by 1. The response, and detailView, are hard-coded response types in the client library, so THEY succeed. But if there's an action right after it, its callback is never fired. The timing is tricky, but that seems to be the clearest pattern.
But IMO I would still resolve this with a messageId that the client generates, includes with each action, and the server returns intact, rather than having both sides "guess" where the other is. There may be other edge cases where this can get out of sync, and it's a super simple solution that basically guarantees it can't happen.
It would also be nice for analytics like NewRelic where you're trying client/server calls together in a report.
Evan Tahler @evantahler Jan 27 2015 12:40
@crrobinson14 This is a lot of stuff!
lets see:
Chad Robinson @crrobinson14 Jan 27 2015 12:40
configry
Errr sorry
Evan Tahler @evantahler Jan 27 2015 12:41
1) Sure, feel free to change the GET to a POST for the client http action
(the length limits makes sesnse as a reason to justify this)
PR
Chad Robinson @crrobinson14 Jan 27 2015 12:41
k that's easy
Evan Tahler @evantahler Jan 27 2015 12:41
The message counter is a little harder
I think we always want to trust the server's response
Chad Robinson @crrobinson14 Jan 27 2015 12:42
It's weird. It seems to only happen if you do a room join BEFORE the WebSocket is connected.
Evan Tahler @evantahler Jan 27 2015 12:42
well, you can't join a room before the WS is connected
HTTP clients don't have message counters
they aren't stateful
and only WS clients can join rooms
the client will attempt to cache any roomAdd commands if you aren't connected, and apply them once you are
but you techincally are not connected
Chad Robinson @crrobinson14 Jan 27 2015 12:43
You sort of can. The library remembers your rooms and re-joins them.
Right, that's what I mean.
But should the client have to track all this?
Evan Tahler @evantahler Jan 27 2015 12:44
the transistion is what screws is up
I think the trick might have more to do with resetting the message counter to 0 once you connect
Chad Robinson @crrobinson14 Jan 27 2015 12:44
I guess that's a non-code fix - to document that clients shouldn't attempt a room join without a socket connected. But it makes me wonder if there might be other triggers. It's only the message count that's off - by 1.
Evan Tahler @evantahler Jan 27 2015 12:44
(wow! gitter is flipping the order of my messages!)
I still want to support it
Chad Robinson @crrobinson14 Jan 27 2015 12:45
I still like the idea of a messageId - that's how we matched up responses in our previous framework. But totally open to suggestions if you hav a better idea.
Evan Tahler @evantahler Jan 27 2015 12:45
If you can come up with a failing test, I'm totally happy to try and fix it
I think we'll need more seperation between HTTP and WS actions, so they can have seperate message counters, etc
Chad Robinson @crrobinson14 Jan 27 2015 12:46
The ID makes sense from another standpoint too. Imagine an async call that takes a half second to hit some other Web service (we hit the YouTube API which is MIND-bogglingly slow. Sometimes a second or two per request.
Then you call another action in the meantime and it returns first.
Evan Tahler @evantahler Jan 27 2015 12:46
That's excatly what it's for
Chad Robinson @crrobinson14 Jan 27 2015 12:46
How can the client know to match these up if it's using essentially an index.
Evan Tahler @evantahler Jan 27 2015 12:46
there's a simultaniusActions limit there too to help that out
Chad Robinson @crrobinson14 Jan 27 2015 12:47
Hmmm
Evan Tahler @evantahler Jan 27 2015 12:47
assuming both the client and server start a 0, both should work out fine
like you point out, it's wacky when the client starts above 0
Chad Robinson @crrobinson14 Jan 27 2015 12:47
Well, the client starts at NaN. ;)
Evan Tahler @evantahler Jan 27 2015 12:47
exactly :D
Chad Robinson @crrobinson14 Jan 27 2015 12:47
actionheroClient.js:1877 sending roomAdd NaN
2015-01-27 15:42:30.345actionheroClient.js:1816 opened 0
2015-01-27 15:42:30.346actionheroClient.js:1877 sending detailsView 1
That's from a few console.logs I added to the client while debugging, dumping messageCpount.
Evan Tahler @evantahler Jan 27 2015 12:48
I'm totally open to the idea of the client setting MessageID themselves, and the server just passing it though
but then we need really get this PR out first evantahler/actionhero#561
Chad Robinson @crrobinson14 Jan 27 2015 12:48
Right, I didn't understand the comment in there. What is that change doing?
Evan Tahler @evantahler Jan 27 2015 12:49
There' s a couple of problems with the actionProcessor,
I'll add them to the issue
Chad Robinson @crrobinson14 Jan 27 2015 12:49
ok
As for a failing case, it's tricky. I can give it a go but it might be a few days - we're pre-demo-milestone here. I can't send the whole app - it's a huge AngularJS front-end with a specific database schema to run it. Maybe I can extract just enough.
I haven't been able to trigger it if I block all requests until the WebSocket is up.
What led me to it, actually, was that we've been entering our app from the home page this whole time and never had an issue. When we enter the app directly from the detail page URL where it has enough information to get going immediately, it sends the room join as a very early action and triggers the offset.
Evan Tahler @evantahler Jan 27 2015 12:52
ah
Chad Robinson @crrobinson14 Jan 27 2015 12:53
The messageCount is basically the same as the message ID I was suggesting. I bet there's a 1-line :"fix" here to either include it or obey it on one side or the other. Probably from the client going up to the server, just include the value, and if the server sees it, it respects it.
Evan Tahler @evantahler Jan 27 2015 12:53
Actually, I think the bug is here:
https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L87-L96
that needs to chained better
Chad Robinson @crrobinson14 Jan 27 2015 12:54
Well, there's also one here. https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L46
This is the only place messageCount is set, so it's NaN until 'open' is fired.
Evan Tahler @evantahler Jan 27 2015 12:54
I think that's OK Actually
actionWeb https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L152-L175 never updates that counter
Chad Robinson @crrobinson14 Jan 27 2015 12:55
I'm not sure it's OK. It's getting called from here https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js#L106
This code increments the value from 'undefined' making it NaN which is an invalid index into the array of callbacks to remember.
Evan Tahler @evantahler Jan 27 2015 12:56
but the web one never calls self.send
only the WS ones do
Chad Robinson @crrobinson14 Jan 27 2015 12:56
You say that...
But a console.log here is getting fired... :)
Evan Tahler @evantahler Jan 27 2015 12:56
or should anyway :D
Chad Robinson @crrobinson14 Jan 27 2015 12:57
Is it because of some assumption made here? // primus will buffer messages when not connected
roomAdd calls self.send which I believe will call the prototype.
Only the .action() call actually checks and routes the request.
roomAdd is more raw.
Evan Tahler @evantahler Jan 27 2015 12:57
perhaps we just need self.messageCount = 0; on line 35 as well, and to reset it like we do on open
that makes sense!
Chad Robinson @crrobinson14 Jan 27 2015 12:58
Testing
Oh, no that's only a partial fix. It makes the messageCOunt 0 in that block of code. But then roomAdd makes it 1... and then 'open's event handler sets it to back to 0 again. So it sort of flips the problem around without fixing it
Race conditions are fun.
Evan Tahler @evantahler Jan 27 2015 13:00
(this shit is almost imposible to test in a suite... I haven't found a way to use selemnum yet with WS)
Chad Robinson @crrobinson14 Jan 27 2015 13:00
Me neither.
We're using Angular Protractor for E2E which seems to get it, but it's slow. Lots of promises and delays.
Evan Tahler @evantahler Jan 27 2015 13:01
oh wait!
Chad Robinson @crrobinson14 Jan 27 2015 13:01
Question, since this stuff could be queued should this value ever be set tpo 0?
What's the value in resetting it on open? Just because the server will do the same? If so wouldn't sending it along with each message fix that?
Evan Tahler @evantahler Jan 27 2015 13:01
are you calling actions/room add before client.connect(function(err, details){ ... ?
it has to do with reconnects
Chad Robinson @crrobinson14 Jan 27 2015 13:01
No, we checked that.
Evan Tahler @evantahler Jan 27 2015 13:02
when you reconnect, it has to be back to 0
cool
Chad Robinson @crrobinson14 Jan 27 2015 13:02
It's just AFTER that but way before the connection is established
Basically, we don't block on the connection. If we do it totally fixes the issue, it just feels like the wrong fix.
If the connection is up before we start making requests all is fine
Evan Tahler @evantahler Jan 27 2015 13:02
yeah, I'm with you
Chad Robinson @crrobinson14 Jan 27 2015 13:02
A worry is that if you lose your connection you could have this problem recur.
Evan Tahler @evantahler Jan 27 2015 13:02
perhaps
Chad Robinson @crrobinson14 Jan 27 2015 13:02
Duering the time it's re-establishing, new requests could cause the same problem.
Evan Tahler @evantahler Jan 27 2015 13:04
what about evantahler/actionhero#571
that capture the original intent anyway
Chad Robinson @crrobinson14 Jan 27 2015 13:04
Checking
This appears to fix the problem.
Evan Tahler @evantahler Jan 27 2015 13:05
(boom)
sold.
Chad Robinson @crrobinson14 Jan 27 2015 13:05
shaka-laka
Cool, thanks.
Evan Tahler @evantahler Jan 27 2015 13:05
great sluething!
Chad Robinson @crrobinson14 Jan 27 2015 13:05
So I'll still send a PR to change the GET to a POST or do you want to roll that together here?
Evan Tahler @evantahler Jan 27 2015 13:06
I'll merge mine in ASAP
Chad Robinson @crrobinson14 Jan 27 2015 13:06
kk
Evan Tahler @evantahler Jan 27 2015 13:06
please handle the POST in a new PR
the only real rule is don't use any external JS libs (jquery, etc)
I don't want to conflict with anyone who might wrap AH within jquery, angular, etc
Chad Robinson @crrobinson14 Jan 27 2015 13:07
Totally understand. We're jQuery-free here.
Need to think about how best to process this though.
Evan Tahler @evantahler Jan 27 2015 13:07
awesome.
Thanks!
Chad Robinson @crrobinson14 Jan 27 2015 13:07
After some reflection, maybe this isn't the right approach.
You already have an httpMethod override option here...
Evan Tahler @evantahler Jan 27 2015 13:08
oh yeah, I guess you can override it
ha
but it would be nice to fix globally
Chad Robinson @crrobinson14 Jan 27 2015 13:08
Our app is very specific about methods in its routes. We're considering routing write-class requests to specific servers and rate limiting them differently, so we're being strict about using POST to create, PUT to update, GET to retrieve, etc.
A global fix in that context would require a copy of the routing config block.
Evan Tahler @evantahler Jan 27 2015 13:09
got it
I actually don't think that we ever block actions because of a miss-matched HTTP verb
like, you can always get to any action with ?/action=
?action=NAME_OF_ACTION
you can block in middleware of course
Chad Robinson @crrobinson14 Jan 27 2015 13:10
That's if you have queryRouting enabled. We're considering disabling it.
Evan Tahler @evantahler Jan 27 2015 13:10
ahh
well, you can always return api.routes.routes in an action
it's all stored in one object
(check it out in grunt console)
Chad Robinson @crrobinson14 Jan 27 2015 13:11
Query-based endpoints are much harder to cache in CDNs. I mean, they work, but you can swap params around and do other things that caching layers like to drop for efficiency's sake. Like ?action=A&param=B and ?param=B&action=A are legit queries to ActionHero, but generate two different cache objects. They're common ways to drive traffic in a DDoS.
Evan Tahler @evantahler Jan 27 2015 13:12
yup, totally makes sense
(hence the option)
Chad Robinson @crrobinson14 Jan 27 2015 13:12
If you only allow (GET) /api/action/param then you can drop query strings for get requests, cache the heck out of them, and limit your DDoS exposure (somewhat)
Oh, that's totally workable in our app - we're already essentially doing that.
Evan Tahler @evantahler Jan 27 2015 13:12
awesome
Chad Robinson @crrobinson14 Jan 27 2015 13:13
I was just suggesting that maybe change GET->POST as the default in the library was not as great an idea as I thought.
Evan Tahler @evantahler Jan 27 2015 13:13
back to work for me. Keep sending bugs!
Chad Robinson @crrobinson14 Jan 27 2015 13:13
ciao, thanks for the thoughts
Jason Marmon @jtmarmon Jan 27 2015 21:44
@harlanmilkove did you ever have any luck debugging that issue? i think i might be running into the same thing
Jason Marmon @jtmarmon Jan 29 2015 10:56
turns out it was AWS's fault.
also, a command line debugging tool for AH would be awesome
especially for testing tasks
Chad Robinson @crrobinson14 Jan 29 2015 16:31
@jtmarmon What did you have in mind? We were thinking the same thing. Our DevOps team has asked us whether we can make a command-line wrapper to execute actions so they can do maintenance things like force-running tasks, sending room broadcasts, and running actions to do things like update a user or whatever.
Evan Tahler @evantahler Jan 29 2015 16:53
We have the GRUNT CONSOLE already
You can also always curl locally...
Do you want to extend the binary with -- runAction.?
Danial @DanialK Jan 29 2015 17:24
Hey guys, i'm building something right now and it's kinda getting my head around it with actionhero and I don't want to use any other queue library if possible. When you enqueue a job in a queue (which btw it's the only job that gets enqueued in that queue) multiple times with different params, is there anyway with actionhero to set the concurrency to 1 (like async.queue or kue.process) so it runs the jobs only in that queue one by one and not in parallel( I want the rest of the task run in parallel )? (we also have couple of workers which we need them for parallel tasks in other queues so setting the min max number of processors to 1 is not a good solution)
Sorry to post it here it's kinda urgent, thanks :)
Danial @DanialK Jan 29 2015 17:42
*kinda confusing
Evan Tahler @evantahler Jan 29 2015 18:36
2 ways: only have 1 worker on that queu. Or look at node-resque plugins. Worker lock is the one you want
Name the plugins in your task definition.
Danial @DanialK Jan 29 2015 19:36
How can I only assign one worker for a queue?
In the latest resque there isn't any worker-lock plugin (only queulock and joblock)and I couldn't find anything on npm? do you have a link by any chance?
Thanks Evan !!
RENARD Laurent @lorenzofox3 Jan 29 2015 19:38
Hi all ! congrats and thanks @evantahler for this great framework !
Danial @DanialK Jan 29 2015 20:09
jobLock renqueues the task if it's locked which changes the order of execution, I need it to pop the task one by one like the way it's saved in redis(resque:queue:myQueue) and process the next one when the current job either finished or failed, I don't think it can be fixed in the plugin layer otherwise I would write my own. Maybe associating one worker to the queue fix this but i'm not sure how and I couldn't find anything in the documentation. Thanks anyways though !
Evan Tahler @evantahler Jan 29 2015 23:16
Nothing will maintain order sadly. You could attempt to enqueAt and guess times, but that's probably a terrible idea.
Perhaps a redis key for what step you are on. Workers pop jobs and if it's the wrong one they re enque for a minute latef
omichowdhury @omichowdhury Jan 30 2015 14:10
@DanialK we had an orchestration problem to solve like that. We did it by storing the order in redis, queuing the first task and adding a thing at the end of each task that checks redis and queues the next one
omichowdhury @omichowdhury Jan 30 2015 14:16
that basic approach scales in complexity too - we had a self-modifying tree of tasks to execute - since each task only knows about its neighbours
Evan Tahler @evantahler Jan 30 2015 15:22
I like this idea!
Jason Marmon @jtmarmon Jan 31 2015 08:02
yup we're actually doing a similar thing for rolling distribution of lead over a set of customers: once we sent a lead to one agent, the task requeues itself and continues distributing to the remaining agents at 5 min intervals until there are none left. pretty handy approach (although sometimes i have nightmares about a mutant task that never stops requeueing itself)
Jason Marmon @jtmarmon Jan 31 2015 08:13
(and texts all of our agents at 3 in the morning)
Evan Tahler @evantahler Jan 31 2015 09:00
It's a good defensive pattern to make all tasks "idempotent". This means that they always check an external source for latest status. For example if you have a task to send a welcome email, you would also have a related DB column of sentEmailAt. The task would send the message and update the column. This way, if you ended up with more than one task somehow, only one would fire because you would of course check that the column wAs null first.
Jason Marmon @jtmarmon Jan 31 2015 09:01
yeah that's actually exactly how it works, but i'm still paranoid. tests on tests on tests
Evan Tahler @evantahler Jan 31 2015 09:01
the best programmer is a paranoid programmer.
Jason Marmon @jtmarmon Jan 31 2015 09:02
:grin:
Evan Tahler @evantahler Jan 31 2015 09:02
That patern has helped me a lot when queues get long too. I've got some "sync with external vendor" tasks
Rather than enqueue the data in the task, I just write the user id and the task looks it up.
It's possible for the data to have changed while the task was enqueued so this way stale data is never used
Like if one of your agents changed third phone number really fast :)
*changed thier
Jason Marmon @jtmarmon Jan 31 2015 09:05
yeah. that's how i've been doing all of my task queueing. the only issue for me is that although checking the database helps make the task a bit more idempotent, it's still has quite a bit of state because it's enqueued/not enqueued at any given moment. considering I have some concerns about the reliability of elasticache, I need a periodic task that checks the database for lost leads hanging around in the nether :laughing:
Chad Robinson @crrobinson14 Jan 31 2015 11:13
I'm running into an issue with how chat room members are maintained. It doesn't look like there's any mechanism to "clear" these Redis keys. If you kill and restart a node, the system thinks those viewers are still there.
It's like there needs to be something at server start that uses the 'host' field to go nuke any entries it might have had (but clearly couldn't, anymore).
The real use-case here is to get a list of popular rooms by member count so if anybody has any suggestions I'm all ears!
Chad Robinson @crrobinson14 Jan 31 2015 12:35
One option I'm evaluating is a background task that posts to a new cache key with the current server's ID and token, but an expiration set on the record. Say, posting every 5-10 seconds with an expiration of 30 or so.
Then a background task could run periodically to enumerate servers and delete records for any nodes that have been disconnected. To do that would require posting a reverse-lookup key for room-adds - a hash per server of connection:room maps. It's a bunch of extra moving pieces but the only solution I could think of right now.
Evan Tahler @evantahler Jan 31 2015 18:02
It's possible to get a list of all servers currently connected too.
Chad Robinson @crrobinson14 Jan 31 2015 20:06
As a hack, for now, we wrote a piece of middleware that handles logging and purging. When a SERVER starts, it sets a key in Redis with an expiration, and it updates that expiration periodically. When a client connects, we do something similiar, and although it's ugly, Redis is fast... we update all clients on all servers with an expiring key in Redis.
As nasty as that sounds, it makes it easy to make a single background task at that point that goes through chatroom members and verifies that the clients are still connected and the servers are still valid. It removes any entries where that isn't so.
We've also just run into an issue where node-resque had a lock that wasn't getting cleared, and one of our background tasks wasn't being run. This is on a node that's been restarted a lot (a QA integration box). It only happens with a "real" Redis server of course because fakeredis purges each boot
We will probably implement something like https://github.com/lantins/resque-lock-timeout to deal with this.
Evan Tahler @evantahler Jan 31 2015 20:36
There is a 1 hour lock timeout https://github.com/taskrabbit/node-resque/blob/master/lib/plugins/jobLock.js which should be configurable.
Chad Robinson @crrobinson14 Feb 03 2015 20:56
Going to public Beta in a few weeks. Can't wait to show all you guys what we've wrought. ;)
ActionHero was a huge time-saver. Evan, totally owe you a beer if you're ever in town.
Evan Tahler @evantahler Feb 03 2015 22:44
Congrats!
Sebastian Dechant @S3bb1 Feb 03 2015 22:44
I'm supporting your statement @crrobinson14 ... thx Evan for the nice project! that must be said ;-)
Evan Tahler @evantahler Feb 03 2015 22:44
And yay beers!
Mildly related: I'll be at NodeSummit. Anyone coming?
Sebastian Dechant @S3bb1 Feb 03 2015 22:46
whish to be there ... but from germany it's a litte bit wide to travel ;-)
chimmelb @chimmelb Feb 04 2015 12:38
I wanted to confirm something regarding periodic tasks. When a actionhero server/node starts, will it create a new periodic task if not existing, and respect any existing otherwise? I want to create a task that runs twice a day, so a period of 12 hours. I do not want it to run more than twice a day (especially during cloud tests when I create and kill many servers a day).
chimmelb @chimmelb Feb 04 2015 12:56
I think I see my answer in the docs at creating a task, at task.frequency. There will be only one, which is good, and I'm assuming the period does not reset with the server, so everything looks in order!
Evan Tahler @evantahler Feb 04 2015 15:16
Should be!
There is also a grunt task to start them up if needed.
Chad Robinson @crrobinson14 Feb 05 2015 06:41
@chimmelb I can also confirm that this behaves as you expect. We're relying on it heavily for some much faster items like one every 30s and another every hour. We have no duplication of execution.
Super nice that Evan planned ahead in AH and made it so you can control which nodes run tasks and which handle Web requests. We're using this to offload our task execution. It's not so much that tasks are hard to run, but given NodeJS's single-threaded nature it DOES affect the Web heads if they run tasks. Offloading this makes sense.
chimmelb @chimmelb Feb 05 2015 07:14
Thanks! @crrobinson14 and @evantahler
Evan Tahler @evantahler Feb 05 2015 08:19
and remember, the task system is really just resque under the hood. You can write "workers" in many laguages:
https://github.com/taskrabbit/node-resque
https://github.com/resque/resque
https://github.com/binarydud/pyres
https://github.com/gresrun/jesque
Dave Shapiro @dsshap Feb 08 2015 07:35
@evantahler just started to work on v2 of an api and started reading the release history, awesome stuff! I am especially excited about the using clusters with RPC!
that wasn't present in v6.4.4, these changes are going to make life much better for me, thank you
Evan Tahler @evantahler Feb 08 2015 11:26
awesome! What are you working on @dsshap? There should be a lot of changes from v7 to v10
Dave Shapiro @dsshap Feb 08 2015 12:31
some epic stuff
Evan Tahler @evantahler Feb 08 2015 12:36
@/all V10.0.4 is up! https://github.com/evantahler/actionhero/releases/tag/v10.0.4
Chad Robinson @crrobinson14 Feb 08 2015 12:37
Nice!
Hey, this middleware PR is going to be for 11.x right? Is there a way I should format it to make that easy? I was wondering if you wanted to start the 11.x branch NOW and I'll re-submit it against that instead of master.
Evan Tahler @evantahler Feb 08 2015 12:39
good call @crrobinson14 https://github.com/evantahler/actionhero/tree/v0.11.0
Evan Tahler @evantahler Feb 08 2015 17:36
Note: I've renanmed the https://github.com/evantahler/actionhero-client package (and unpublished the old one from NPM). There were many severe breaking changes, so now seemed like the time to make the switch
Sebastian Dechant @S3bb1 Feb 09 2015 12:15
Hi, anyone some good ideas how i can test my AH plugin independent from Actionhero ? Or i have to include the whole AH Framework ... makes it difficultly to test automatically
Evan Tahler @evantahler Feb 09 2015 20:08
take a look at how I test the client: https://github.com/evantahler/actionhero-client
actionhero#master is a devDependency
and then in the test suite I can boot a real actionhero server, changing the config (like working_dir) https://github.com/evantahler/actionhero-client/blob/master/test/setup.js
for plugins, just add a plugin path that is something like ./../../
@S3bb1 ^
Sebastian Dechant @S3bb1 Feb 09 2015 22:24
THX @evanthaler will have a look into it :-)
Jason Marmon @jtmarmon Feb 10 2015 07:34
hey @evantahler - i'm on 9.4.1 still and i'm noticing that one task that does health checks on a server is holding up all the other tasks in that queue when the request times out. how can i get around that?
Jason Marmon @jtmarmon Feb 10 2015 07:39
nothing changes when the tasks are on different queues either
edit: hmm nevermind i guess workers are slow
Evan Tahler @evantahler Feb 10 2015 08:46
Hah. Or have more workers.
Sebastian Dechant @S3bb1 Feb 10 2015 13:28
@evantahler just installed AH Client and want to run the tests and get following error :
0 passing (150ms)
1 failing
1) integration "before each" hook:
Uncaught TypeError: Object #<Object> has no method 'log'
at finalStartInitializer (c:\Users\sebastian.dechant\Documents\GitHub\test
\node_modules\actionhero-client\node_modules\actionhero\actionhero.js:202:16)
do you know this problem ?
Evan Tahler @evantahler Feb 10 2015 13:47
note: nodejitsu is shutting down in a few months. moving demo.actionherojs.com to heroku evantahler/actionhero#580
@S3bb1 got any more of those logs?
and node/npm versions
Jason Marmon @jtmarmon Feb 10 2015 13:52
weird...that totally just happened to me and i completely forgot why (but i'm like 90% sure i fixed it)
Evan Tahler @evantahler Feb 10 2015 13:53
that error is self.api.log... so if you don't have api.log, you probably skipped all the initilizers somehow
what's your working directory, config path, etc
Sebastian Dechant @S3bb1 Feb 10 2015 13:56
Hmmm simply installed the ah client and run mocha nothing else :-/
Evan Tahler @evantahler Feb 10 2015 13:57
I've also never tried on win
(nor can I)
let me try from scratc
node version?
yeah... I can't break it in that way
oh!
checkout test/setup.js. Perhaps all the "/" needs to be path.sep()
give that a whirl @S3bb1
Evan Tahler @evantahler Feb 10 2015 18:26
Any luck @s3bb1
?
Sebastian Dechant @S3bb1 Feb 10 2015 20:33
sorry... was sleeping ... got it now
Sebastian Dechant @S3bb1 Feb 10 2015 20:43
its an issue within the actionhero.js ... will generate a PR for this in the next hour
Evan Tahler @evantahler Feb 11 2015 09:05
@S3bb1 What was it?
omichowdhury @omichowdhury Feb 11 2015 09:26
@evantahler We're just starting out upgrade to v10 - I noticed "resque scheduler polling" is getting logged every second on debug now
That's...kinda annoying?
:)
Evan Tahler @evantahler Feb 11 2015 09:27
get out of debug mode! go to info
It's debug... so yeah, it will be annoying.
the defaults now is the info log level
https://github.com/evantahler/actionhero/blob/master/config/logger.js#L14
omichowdhury @omichowdhury Feb 11 2015 09:30
Yeah I'd kinda assumed there was a "trace" level below debug so we do "this is how something got run" level logging at debug
omichowdhury @omichowdhury Feb 11 2015 09:37
No point in arguing logging levels, just wanted to register my opinion on the matter. Hoping to see some perf increases with the move to multiWorkers, will let you know
omichowdhury @omichowdhury Feb 11 2015 09:54
@evantahler So would you say use notice for "this API call was made", info for "mongo was queried" and debug for "reusing mongo cached connection"
Evan Tahler @evantahler Feb 11 2015 10:02
I guess it's really up to you & your application and what resolution you feel maters for production
to me, debug is "literally everything you might need to sort out a problem"
"info" is run in development ENV, so it's verbose but not annoying
you may run your app in production with INFO, or you may write it with a higher level if you don't want per-connection messages
up to you
personally, I would never log queries unless DEBUG
but you totally can!
omichowdhury @omichowdhury Feb 11 2015 10:06
yeah our current setup is to run at debug during development and info in production (because I assumed a trace below debug)
I'll probably do a PR against our codebase to push logs up a level and run production at notice
Evan Tahler @evantahler Feb 11 2015 10:23
cool. I'm also happy to change what the levels things log at. However, there is no trace
Here are the levels BTW https://github.com/evantahler/actionhero/blob/master/initializers/logger.js#L19-L27
Evan Tahler @evantahler Feb 11 2015 14:18
Hey! Lets get some actionhero tshirts made! http://teespring.com/actionhero-t-shirts
omichowdhury @omichowdhury Feb 11 2015 16:05
sweet! got mine :)
Sebastian Dechant @S3bb1 Feb 11 2015 22:48
@evantahler see already merged pull request ;-) evantahler/actionhero#581
had a second "." in my AH location ... c:\Users\sebastian.dechant\Documents\GitHub... so when the initializers are loading into the "self.initializers" object the key was "c:\Users\sebastian" for every initializer. In the actionhero.js the path was splitted with "." and it took the index 0 for the key "var initializer = f.split('.')[0];" ... so all initializers were broken because they had the same key
Dave Shapiro @dsshap Feb 12 2015 07:54
having issues with server starting up when i include "ah-newrelic-plugin"
Evan Tahler @evantahler Feb 12 2015 08:05
@dsshap have any traces or errors for us?
Dave Shapiro @dsshap Feb 12 2015 10:03
@evantahler not the server would just lock up, even with debug level for logs
Evan Tahler @evantahler Feb 12 2015 10:04
It's possible I haven't updated that for v10. Can you open an issue on that github repo
Dave Shapiro @dsshap Feb 12 2015 10:05
it just hangs here:
12:04:00 web.1 | 2015-02-12 12:04:00 - debug: loading initializer: /Users/dave/../app/node_modules/ah-newrelic-plugin/initializers/newrelic.js
12:04:00 web.1 | 2015-02-12 12:04:00 - info: actionhero member 10.1.10.18 has joined the cluster
will do, thanks
Evan Tahler @evantahler Feb 12 2015 21:41
@dsshap try it now
also, oops!
Amine Mouafik @kytwb Feb 12 2015 21:48
hey there
long time :)
just came back from holidays, realized we still run on actionhero 9 (nov'14), time to upgrade
Amine Mouafik @kytwb Feb 13 2015 00:06
https://actionherojs.com/ down for me
Sebastian Dechant @S3bb1 Feb 13 2015 00:31
try http://www.actionherojs.com/ ;-)
Amine Mouafik @kytwb Feb 13 2015 00:31
ah right, my bad
Evan Tahler @evantahler Feb 13 2015 07:08
Yeah, no https from free github pages :(
Amine Mouafik @kytwb Feb 13 2015 07:17
currently upgrading to v10
finished to refactor our intiializers, now refactoring our actions input
Evan Tahler @evantahler Feb 13 2015 12:51
Nice!
Amine Mouafik @kytwb Feb 13 2015 20:18
yep, also upgraded to node 0.12 yesterday and did some pull request on some plugins we use that were incompatible (ah-nodemailer-plugin for instance)
also, we've done something here in addition to ah-sequelize-plugin
a query builder with basic where support, where on assocation, on-demand association include etc.
so every endpoint can return different things based on how its called
/api/human/2 -> {name: 'kytwb'}
/api/human/2?include=parent -> {name: 'kytwb', parent: {name: 'sthg'}}
Amine Mouafik @kytwb Feb 13 2015 20:24
same with /api/human?where[]=sth&where[]=sthelse
will propose when more mature
Neil Craig @neilstuartcraig Feb 16 2015 13:51
Hi guys. I've been lurking in the background a bit with actionhero for a while now and starting contributing a little before christmas then started a new job (with a giant first project which is eating all my time) and got too busy! Anyway, I am updating my actionhero plugins at the moment to be v10 compatible (and tidying up some stupid package versioning mistakes) so wanted to drop you guys a line...
So far, I have got plugins:
Actionhero v10 compatible:
Auth plugin - MongoDB-based auth with support for various options, 2FA will be in there soon via software TOTP. This is beta quality right now.
RBAC ACL plugin - A simple role-based ACL. This is alpha quality.
Not yet actionhero v10 compatible:
Content item plugin - a generic markdown-based content item plugin which is simple but fairly flexible. Probably alpha quality
Session plugin - this is more or less a plugin-ified version of Evan's session handler example. It's really simple but works pretty well.
Dynamic pre/post processor loader - This is not yet plugin-ified but basically allows you to specify for given actions/versions which pre/post processors should be run. This is actually really useful and is very fast in per-action logic execution as just about all the processing is done during the startup process.
So what i'd be very grateful for is any feedback on the above modules, be that bugs, suggestions for improvement or whatever else.
My aim is to create a little suite of core plugins which will allow me to use actionhero as a back-end API with a backbone.marionette front end. I'm not totally sure how that's going to work out yet but my initial sketchups last year went well so I think it'll work well, at least if i ignore accessibility. Lots still to do anyway!
Cheers all
Neil
Amine Mouafik @kytwb Feb 16 2015 20:14
@neilstuartcraig good job man! might be interested in using and contributing to some of your plugins
Neil Craig @neilstuartcraig Feb 17 2015 02:48
@kytwb - sounds great, i'd be very interested in both getting people using them and contributing. It's worth saying that I haven't used the plugins in production yet, just on my development stack - no doubt some issues/bugs etc. will emerge but I want to tackle those ASAP and get the plugins into the best shape they can be,
I forgot to mention but I am also very keen to make the documentation good - I often find that is a real barrier to people using open source software.
I'll try to v10-ise the rest of the plugins over the next week or so.
Cheers!
Oh, and BTW, the auth, ACL and session plugins are designed to be completely modular (i.e. they're not coupled at all) but to work together easily - just to allow people to get off the ground without too much effort. I always think it's simpler to have things work together in a demonstrable fashion out of the box, even if it's not the way people will use them in reality
omichowdhury @omichowdhury Feb 17 2015 07:01
Hey @neilstuartcraig I use marionette too, although not directly with AH (external API servers are all Java). About your dynamic pre/post processor plugin - I noticed there was a PR being worked for a future AH release that adds this feature (evantahler/actionhero#570)
Neil Craig @neilstuartcraig Feb 17 2015 07:05
Hi @omichowdhury. I had a very brief discussion about this a few weeks ago...
Sorry, hit the wrong button…Anyway, the discussion is here: evantahler/actionhero#570
Sorry, hit the wrong button…Anyway, the discussion is here: evantahler/actionhero#570
Guess you saw that. I was told it was something a bit different but if not, my code might help - it’s very efficient as so much of the computation is done at startup time
omichowdhury @omichowdhury Feb 17 2015 07:08
ah gotcha, the difference makes sense. Would be interesting to see numbers of the perf difference
Neil Craig @neilstuartcraig Feb 17 2015 07:08
Ahh, this thing is going crazy. Apologies for the confusion.
I’m hoping to produce a small marionette <-> actionhero client side module BTW. Havent given it much thought yet though
i’ve not looked at the diffeences yet - it;d be good to understand them. i’m pretty confident my code is (or at least can be) extremely fast - the per action processing is more or less an “if"
Chad Robinson @crrobinson14 Feb 17 2015 19:57
Just to clarify, the intent behind #570 is to provide a more "declarative" approach. That is, it allows middleware requirements for an action to be defined IN the action, as part of its metadata - the same way you define things like inputs. This is ideal when your actions require a mix of middleware components.
It doesn't necessarily conflict with other approaches which might be better suited to en-masse configurations. However, Evan has suggested a third, "global" option that bridges this gap. Do we need a discussion? There are breaking changes in 11.x for what you've listed above.
Neil Craig @neilstuartcraig Feb 18 2015 01:42
Ah great, thanks for the clarification @crrobinson14 - I did think about that method too but decided i wanted to have a single file which described everything - a matter of taste and use-case i guess.
It’d be relatively simple to adapt my code to read in the data from actions, in fact my code reads in actions to some extent anyway. I guess you’ve written your code anyway though?
Neil Craig @neilstuartcraig Feb 18 2015 03:03
@evantahler (or anyone else who can help) I'm having some issues (which are probably me doing something stupid) with actionhero 10 in terms of the specHelper. It doesn't seem to be seeing/looking at my projects actions, it only sees the default ah actions and i therefore see an error when i run e.g.
api.specHelper.runAction('TDPAHContentItem/create', ci, function(response, connection) { ... }
This is in my local, working copy of my plugins which have not been npm installed - once i install the plugin correctly into an ah install, it's all fine.
An example is my "content item" plugin: https://github.com/neilstuartcraig/TDPAHContentItemPlugin
Any advice or more info I can provide?
I don't think this was the case on actionhero 9 BTW - maybe i'm wrong though
omichowdhury @omichowdhury Feb 18 2015 05:20
@neilstuartcraig do you see the plugin loaded at startup during a test run? I'm guessing it's a configuration path thing - make sure your config files are being used at all. sticking a console.log inside a config file usually tells you if its being loaded
salles @sallespro Feb 18 2015 06:16
hello guys, i just wnat to say hi everybody and share my enthusiasm with AH.
@S3bb1 contributed with excellent code for the AH dashboard. For angular enthusiasts it has a plus.
@omichowdhury has been very active and i couldn’t even follow all the spec-chat going on with @evantahler et all.
in my learing with AH i found very few plug-ins or samples and now there’s a bunch out there and a good motivation to upgrade to v10 +
salles @sallespro Feb 18 2015 06:21
i find myself looking at different approaches for session, auth, & endpoint access authorization i would suggest we try to bring one set together.
everybody will have a good startig point and all the freedom AH provides to play with preProcessors and do it any other way one my find more suitable.
i have used https://github.com/panjiesw/ah-auth-plugin and liked the JSON Web Token
salles @sallespro Feb 18 2015 06:26
@neilstuartcraig now brings us another set with Auth, Session and some Content too.
Wouldn't it be a goal to the community to put together such a kick-off full stack app with enough to authenticate users and manage tasks & all with the dashboard ?
Neil Craig @neilstuartcraig Feb 18 2015 07:44
@sallespro that's what I'm doing right now :-). It's my version of it of course but I'm building the basic tooling for an actionhero / marionette website system/framework
salles @sallespro Feb 18 2015 07:47
@neilstuartcraig we’re often sharing the same need for user auth. even though everyone will eventually build a solution, the AH community outcome would be a +
Neil Craig @neilstuartcraig Feb 18 2015 08:17
Yeah it would be cool to have a “go to” for at least simple auth. Why don’t we create an issue (ot soemthing else) to gather requirements from everyone who’s interested? I’ve engineered/roadmapped my plugin for a particular need and based on my experience - i ultimately want it to be an enterprise-level auth mechanism, hence the focus on strong encryption and support for expiration, complexity of password etc. NExt on my list is TOTP, i’m undecided about oath as i don’t like it much but it’s super useful for some people…maybe a pluggable auth system is the way to go
Evan Tahler @evantahler Feb 18 2015 08:27
I highly suggest that you use passport. It's the most common Auth middleware for nose (as far as I can tell) and already has "plugins" for tons of strategies. I think someone already made a ah-passport middleware.
Regardless of if your goal is ramping up new people, interoperability, or sanity, passport is the way to go
I guess no one ever made a NPM package for it, but here's a starting point https://gist.github.com/juancgarcia/e4caf5dc7474769f5137
Someone make a package!
Neil Craig @neilstuartcraig Feb 18 2015 08:36
Hmm, that’s a good call @evantahler - thanks for the pointer, I guess i got caught up with thinking about what i wanted without looking around enough. I’ll check it out in more detail - i saw a couple of things i’m not too keen on but maybe i can get around them ;-)
The list of passport plugins is here BTW: https://github.com/jaredhanson/passport/wiki/Strategies#multi-factor
Sebastian Dechant @S3bb1 Feb 18 2015 12:51
yeah! a passport module for ah would be nice! would like to use it and contributing to this!
Neil Craig @neilstuartcraig Feb 18 2015 12:53
I'm happy to make a start on the plugin for passport unless anyone else wants to. Might take me a few days though
Sebastian Dechant @S3bb1 Feb 18 2015 12:57
if you need some ideas or something, feel free to ask :) i'm using passport roundabout 1,5 years
Neil Craig @neilstuartcraig Feb 18 2015 12:59
Oh cool! That's great news @S3bb1 - I'm looking forward to learning about it.
Sebastian Dechant @S3bb1 Feb 18 2015 13:01
we've published 2 passport modules too, would like to see them in action with ah :)
Neil Craig @neilstuartcraig Feb 18 2015 13:03
Even better! :-). I'm going to finish the bones of my installer meta package for all my plugins then I'll make a start. I'll keep you guys up to date on here
Sebastian Dechant @S3bb1 Feb 18 2015 13:04
:+1:
Evan Tahler @evantahler Feb 18 2015 19:03
Huzzah for passport!
Chad Robinson @crrobinson14 Feb 18 2015 20:39
Not to be a shill... but we've also had really good luck with Auth0. If you have a bit of budget and don't feel like writing front-end auth code at all, they make it super-easy for AngularJS and other apps to integrate.
It uses a JWT that gets auto-added as a header to future requests, and you can easily pull this out in middleware in AH.
@evantahler I'm a little out of date on discussions. I'm coming back up for air. Did you want me to complete what you had suggested for 11.x re: middleware handling, or have recent discussions changed any of that?
salles @sallespro Feb 19 2015 05:18
@crrobinson14 Auth0 is pretty good. passport too. for different reasons. while Auth0 connects your project with a thin layer of SaaS for identity management, passport hels integrate with a world of strategies. i believe we miss a little stronger compared to what we currently have, simple auth ah-brewed plugin with persistence for a start.
As time goes by, we’ll naturally take decisions - project wise - to use a more middleware/modular approach such as passport or even the top abstraction tier offered by Auth0.
Evan Tahler @evantahler Feb 19 2015 08:24
Auth: I vote for passport because I care most about onboarding people to the project. It's free and more popular.
@crrobinson14 no changes! Keep that middleware refactor coming!
Evan Tahler @evantahler Feb 19 2015 08:30
@/all lets talk about generators evantahler/actionhero#590
salles @sallespro Feb 19 2015 08:32
totally worth it
Evan Tahler @evantahler Feb 19 2015 08:36
Please make notes in the GH issue. I imagine this will be polarizing, and I would like to keep a record on how we got to whatever decision we make.
Jason Marmon @jtmarmon Feb 23 2015 08:08
hey @evantahler - one thing i think is missing from the awesome task system is a chron-like system for scheduling tasks. currently you can set periodic tasks, but they'll run when the server boots and then again after the periodic interval, which isn't really useful for stuff that you only want to occur at certain times (in our case, aggregating listing data and sending push notifications to users). is this something you'd be interested in as a core feature, or rather as a plugin?
omichowdhury @omichowdhury Feb 23 2015 08:13
@jtmarmon you can use api.tasks.enqueueAt to queue tasks to happen on a timestamp
ah just understood the use case - run the task at 2pm every day
Jason Marmon @jtmarmon Feb 23 2015 08:16
yep yep - seems like that would be something that would be useful to have for people, since the task system is a nice replacement for chron but doesn't quite fill that use case (which seems like it'd be commonplace)
Evan Tahler @evantahler Feb 23 2015 08:22
@jtmarmon so that's distributed cron. It's a tricky problem. We solved it in ruby + rescue with https://github.com/taskrabbit/resque-bus (look for the heartbeat section). The node port of it https://github.com/taskrabbit/node-resquebus doesn't have the heartbeat yet.
The way it works is you have a normal periodic task run every minute and publish the time. There are some keys/locks in redis to ensure that all minutes eventually get published, even if the queue is backed up
The job that works that minute then piblishes a new event called "heartbeat" that you can then subscribe to with rescue-bus
The reason this is tricky is because you want to gurantee that each cron job is worked exactly and only once, no matter how many servers/nodes/clusters you have
Jason Marmon @jtmarmon Feb 23 2015 08:25
ah interesting
Evan Tahler @evantahler Feb 23 2015 08:25
So... I guess the ask is to make an issue in the resque-bus project to implement the heartbeat :)
In general though, I don't think I want to bake rescue-bus into actionhero
Jason Marmon @jtmarmon Feb 23 2015 08:27
right, fair enough. it seems like a hacky solution could just be a periodic task (once every minute i suppose) to check if there is a task of type x enqueued at some point in the future, and if it's not, enqueue it
then you just use existing solutions for the distributed cron issue
omichowdhury @omichowdhury Feb 23 2015 08:28
or you could have a task requeue itself in 24 hours
Jason Marmon @jtmarmon Feb 23 2015 08:29
yeah true, but then that requires modification of the task itself
which is gross
:tongue:
then again, seeing more periodic task logs in my AH logs is also gross
Evan Tahler @evantahler Feb 23 2015 08:29
There's an issue to change the log levels :)
Jason Marmon @jtmarmon Feb 23 2015 08:30
dónde
Evan Tahler @evantahler Feb 23 2015 08:31
This could be done simpler with api.cache
Run the job every min. Check in the cache how long it wa since the last timestamp. Run if old. If you run, save a timestamp in the cache
So 99% of the time the job will be a no-op
That's a lot simpler than bundling rescuebus into the project
Jason Marmon @jtmarmon Feb 23 2015 08:33
hmm i think if we're going the periodic task route, it seems cleaner to just use it as an enqueueing machine because then you utilize the existing system of enqueueAt and such
but yes i agree - cleaner than rescuebus. is there a way to prevent the bajillion no-ops from clogging up my logs?
Evan Tahler @evantahler Feb 23 2015 08:36
If you are worried about log verbosity, and are manually looking at them, might I suggest better tooling?
Splunk/datadog/etc
But until that log level issue, no
Jason Marmon @jtmarmon Feb 23 2015 08:37
yeah i've been meaning to have better log rotation. but i still do sometimes manually dive into the logs to look for reported bugs which might be user error. can you link me the log level issue? didn't see it open on AH or node-rescuebus
Evan Tahler @evantahler Feb 23 2015 09:36
evantahler/actionhero#587
Neil Craig @neilstuartcraig Feb 23 2015 10:32
Hey guys. I don't mean to be obtuse or anything but couldn't you actually use a cron job which runs an ah task? Seems simpler to me. That's what I'd tend to do personally.
Jason Marmon @jtmarmon Feb 23 2015 11:41
I mean you could use a cron job for most of what the existing task system does. i'd rather contain the complexity of my application to the tools AH provides
Neil Craig @neilstuartcraig Feb 23 2015 11:43
Fair enough :-). I was just thinking that cron could be the trigger though. It'd save a load of effort.
Jason Marmon @jtmarmon Feb 23 2015 11:44
yeah...i've never been fond of anything cron related tbh. i think the periodic task solution will work just fine
Neil Craig @neilstuartcraig Feb 23 2015 11:48
I quite like it as a trigger but I guess that's just personal preference. I suppose it's not necessarily super obvious that a cron job exists. Anyway, it was just a suggestion :-)
Jason Marmon @jtmarmon Feb 23 2015 11:49
yeah definitely a preference thing. i just don't like cron because it feels like it adds a great amount of complexity by going to the OS level for simple application-related things. especially when AH has an (almost) complete replacement. but thanks for the suggestion
Evan Tahler @evantahler Feb 23 2015 12:56
The problem with cron is that then one server becomes special. It's not like the others. You can't kill/create/scale it at will. It doesn't obey 12factor.net
Academically, you have now stored state in a cron file.
Neil Craig @neilstuartcraig Feb 23 2015 12:57
Ah yes, very true. I wasn't considering a cluster.
Evan Tahler @evantahler Feb 23 2015 12:58
It's not only cluster, it's uptime. Even if you only have 1 node process one one server, once you add cron you cannot just copy that server when you need to scale or something goes wrong.
I recommend everyone check out http://12factor.net/
It's pretty severe, but is a great overview of topics to consider.
Evan Tahler @evantahler Feb 23 2015 13:54
I'll be cutting a point release today, so we can get this in ASAP: evantahler/actionhero#593
omichowdhury @omichowdhury Feb 23 2015 13:57
@evantahler sweet! we actually just discovered it this morning too
omichowdhury @omichowdhury Feb 23 2015 14:05
actually it was a totally different issue
were the # of multiWorker workers was varying up and down every second
not sure if that's expected behaviour
Evan Tahler @evantahler Feb 23 2015 15:32
It totally is.
omichowdhury @omichowdhury Feb 23 2015 15:39
I'll chill then
Evan Tahler @evantahler Feb 23 2015 17:38
You can configure min and max processors to be the same if you want consistency.
Evan Tahler @evantahler Feb 24 2015 15:08
Thanks to @submitteddenied for some documentation updates!
֍ DaAwesomeP ֎ @DaAwesomeP Feb 27 2015 20:36
I'm choosing a API system for my next project. This one really fits my needs because it directly supports TCP connections, which is exactly what I need. Is it possible to catch the event of a client's disconnect in real time? Part of my system will track uptime and connections to other machines to make conclusions about if machines are stable or having problems.
Evan Tahler @evantahler Feb 27 2015 20:46
Sure!
Checkout http://www.actionherojs.com/docs/core/middleware.html#connection-middleware
֍ DaAwesomeP ֎ @DaAwesomeP Feb 27 2015 21:33
Great! Thanks!
katopz @katopz Mar 01 2015 23:38
Hi guys! I'm just getting in, so far so good, really impress! :+1:
Greg Coonrod @gcoonrod Mar 02 2015 08:49
Anyone managing ActionHero with Monit?
Neil Craig @neilstuartcraig Mar 02 2015 08:54
I haven't used Minot with it yet but it should be easy. I will do. I think you'll just want the master process monit'd unless you're doing something complex with monit
salles @sallespro Mar 02 2015 08:55
not anymore
Neil Craig @neilstuartcraig Mar 02 2015 08:55
I've used monit with ghost/forever on my blog
salles @sallespro Mar 02 2015 08:57
@gcoonrod just include an upstart script for AH such as
Greg Coonrod @gcoonrod Mar 02 2015 08:59
Currently I'm using this simple monit configuration and I wanted to see if anyone saw any glaring problems.
check process hero with pidfile "<%= hero_dir %>/pids/actionhero-hero"
start program = "/bin/bash -c 'cd <%= hero_dir %> && node --debug ./node_modules/actionhero/bin/actionhero --config=config/build --NODE_ENV=development --title=hero'" as uid "<%= user %>"
stop program = "/usr/bin/pkill -f actionhero"
if 5 restarts within 5 cycles then timeout
salles @sallespro Mar 02 2015 09:03
check process apic with pidfile "/var/run/apic.pid"
start program = "/sbin/start apic"
stop program = "/sbin/stop apic"
#!upstart
description "apic"
author "inc"
start on startup
stop on shutdown
script
echo $$ > /var/run/apic.pid
cd /var/node/apic
exec /var/node/apic/node_modules/.bin/actionHero start >> /var/log/apic.log 2>&1
end script
pre-start script
# Date format same as (new Date()).toISOString() for consistency
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (api) Starting" >> /var/log/apic.log
end script
pre-stop script
rm /var/run/apic.pid
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (api) Stopping" >> /var/log/apic.log
end script
```
Greg Coonrod @gcoonrod Mar 02 2015 09:14
@sallespro So you use the console log transport from AH instead of the file logger?
Evan Tahler @evantahler Mar 02 2015 11:47
I use monit!
Greg Coonrod @gcoonrod Mar 02 2015 11:53
Any obvious issues with the way i've implemented it?
Neil Craig @neilstuartcraig Mar 02 2015 11:55
Nothing major. Personally I'd simplify the start by just calling it via the absolute path but that is just personal
You might also consider some more alerting but you can build it up as you go
Greg Coonrod @gcoonrod Mar 02 2015 11:56
We're deploying AH in different envs and locations between dev and prod so we can't set absolute paths.
Right now we're relying on the winston file logger. But that does leave a gap in instances where AH doesn't come up normally.
Neil Craig @neilstuartcraig Mar 02 2015 12:01
But you have a placeholder for the base path don't you? Anyway, there's no problem with doing what you're doing, it'll work fine.
Neil Craig @neilstuartcraig Mar 02 2015 13:06
Hi guys. I'm looking at this passport plugin. Does anyone have or foresee a need for multiple authentication strategies in one actionhero app/project? The answer will affect how I structure the fundamentals.
Evan Tahler @evantahler Mar 02 2015 13:33
@neilstuartcraig probably- For example, it's really common to allow folks to "auth via facebook, google+, or email+pass'
@gcoonrod looks fine to me... here's mine: https://groups.google.com/forum/#!searchin/actionhero-js/monit/actionhero-js/L9z0ugPOV2k/uFV9nJOc2WoJ
Neil Craig @neilstuartcraig Mar 02 2015 13:35
Oh yeah :-) I'd not thought it through in that sense. No problem. I'll get to it over the next few days.
Greg Coonrod @gcoonrod Mar 02 2015 14:12
@evantahler Was there a recent change in the way api.cache.load handles responding to no object found?
Evan Tahler @evantahler Mar 03 2015 08:42
@gcoonrod you can see the changes here https://github.com/evantahler/actionhero/commits/master/initializers/cache.js Not since October
Greg Coonrod @gcoonrod Mar 03 2015 09:05
@evantahler Thanks! I tracked down the issue.
Sebastian Dechant @S3bb1 Mar 03 2015 10:17
@neilstuartcraig would be great if we can plug any passport moulde into AH to get authenticated
Neil Craig @neilstuartcraig Mar 03 2015 12:46
@s3bb1 yep, agreed! That's what I'm working on right now. I think I've got a method to allow that. The passport docs are very extensive but it looks like it'll work.
Dave Shapiro @dsshap Mar 03 2015 17:24
@evantahler is there any tools you use to profile AH? I am seeing my application eat up a ton of memory after ~1 week (1.83 GB) Its pretty gradual but always happens
Evan Tahler @evantahler Mar 03 2015 23:52
Check out https://strongloop.com/strongblog/node-js-performance-tip-of-the-week-memory-leak-diagnosis/ and https://hacks.mozilla.org/2012/11/tracking-down-memory-leaks-in-node-js-a-node-js-holiday-season/. Basically you need to start counting objects and see which ones aren't getting cleaned up
Neil Craig @neilstuartcraig Mar 04 2015 07:32
Hey guys. I’m still working on the passport plugin but hit an issue. I need to create an object (which contains some functions) in the config file but when i return this from the config file, all the functions on the object are executed which throws errors.
I could obviously set an object on the api root object instead of returning the object from config but that is going to result in some ugly config.
I haven;t hit this issue previously so if anyone has ideas on how to work around it, that’d be great. My code isn’t really shareable yet but i could stick a demo together if that’d help
Evan Tahler @evantahler Mar 04 2015 08:17
_toExpand = false. https://github.com/evantahler/actionhero/blob/master/config/errors.js
Neil Craig @neilstuartcraig Mar 04 2015 10:25
Win. Thanks @evantahler :-)
katopz @katopz Mar 05 2015 01:20
Hey guys, I've app like hipchat(chat/share/todo/blog) to accomplish and decide to use actionhero as a core, i'm trying server side coding and all looking good so far (authen/chat), the question is it's a cross-platform iOS/Android at client side and i'm not sure which is the best way to go? far as i have is xamarin=c#->nodejs helloworld
katopz @katopz Mar 05 2015 01:53
And for other option, I'm now reading http://jxcore.com/ http://loopback.io/ http://nwjs.io/ and try to cook them up with actionhero as a Model/Services layer then present to View with native ui (hope it work) if anyone enter this field before please enlighten me the way out would be nice.
salles @sallespro Mar 05 2015 04:18
@katopz actionhero and actionheroClient library for webview should be enough. iF you intend to have a native UI, it would be necessary to include a web socket native framework like Faye.
katopz @katopz Mar 05 2015 04:32
Thanks @sallespro , from my understand i can use actionhero->primus->faye but all this should go in webview right? is that another way to bind it to faye native framework? or i have to separated it e.g. faye-native for chat and actionhero for something else? i'm not sure it can share same socket or session somehow?
salles @sallespro Mar 05 2015 04:40
webview would be straightforward in anyway. if your’re going native, you can connect to AH server with faye’s native lib for chat/real-time and have https requests from native handled by AH actions & tasks.
you really need a good reason to go native because it makes things very different.
I have seen very successful apps which create a thin native service layer and everything else is Webview. It allows access to both worlds, still trying to keep the code as isomorphic as possible.
salles @sallespro Mar 05 2015 04:50
good reasons to go native are if you are using sensors all the time, doing background stuff on mobile, using AR and things like that.
katopz @katopz Mar 05 2015 06:40
@sallespro cool, if i've to add video call/chat feature later, native should be my safe zone i think :smile:
Evan Tahler @evantahler Mar 05 2015 11:34
I'm activley staying out of the mobile "native vs web" debate... I've got some strong opinions, but this framework makes no call on that :D
I can tell you that folks have used WS happily on mobile web AND there are some pretty good native libraries for websocket, like http://cocoadocs.org/docsets/Primus/0.0.2/
folks also use this with actionhero
salles @sallespro Mar 05 2015 11:39
what makes a strongly opinionated stay actively out of debate ? ans. A framework. :-)
Evan Tahler @evantahler Mar 05 2015 12:33
haha
it's also just not relevent to AH... it should support everything... even the terrible ideas :D
that's my new catch phase these days
I gave a talk the other day about how node is great for eveything... even the bad ideas
https://speakerdeck.com/evantahler/background-jobs-plus-nodejs
OOOH! Embeds!
video and slides here if anyone cares: http://blog.evantahler.com/blog/background-tasks-for-node.html
Chad Robinson @crrobinson14 Mar 05 2015 13:52
Jumping in late, but have to say we're big fans of Ionic here. You get a lot of native bridging out of Cordova and it's super-easy to tie mobile apps into ActionHero. We'll be launching a product using it shortly.
Greg Coonrod @gcoonrod Mar 05 2015 14:50
@evantahler Just watched your async presentation. Good stuff!
fas3r @fas3r Mar 05 2015 17:48
Hello
Evan Tahler @evantahler Mar 06 2015 07:50
hey
Lets talk about log levels: evantahler/actionhero#612 Please add notes in the PR
Greg Coonrod @gcoonrod Mar 06 2015 07:59
Yes, please.
Tobias Braune @tbraune89 Mar 06 2015 13:16
Hey guys, i have a question:
How is it possible to update my data trough an websocket to my application? Just to create an event on the server and listen to it on my client. I got the basics, but didnt found something about creating custom events.
PS: You did some great work!
Tobias Braune @tbraune89 Mar 06 2015 13:34
6. März 2015 22:16 Uhr
Okay i think i'll give this a try: http://stackoverflow.com/a/24703306
Neil Craig @neilstuartcraig Mar 08 2015 13:41
Hey guys. Sorry for the delay on the passport plugin, i have been unwell for a few days now. Anyway, i’m more or less done on a rough draft of the code, just tidying now. I’ll send a link in a few days time to an NPM/github project with some docs etc. I have 2 days of induction training so hoping i can squeeze in some dev/doc time on this. If anyone is in a position to test it once i’ve sent the link, that;d be great
Evan Tahler @evantahler Mar 11 2015 03:18
@/all Does anyone in the bay area want to give a talk on actionhero? One of the node meetup groups wants to have a "framework comparison night", but saddly I'm in the UK for a few months http://www.meetup.com/Node-js-Serverside-Javascripters-Club-SF/events/221063505/
April 2015 - Node.js Meetup
Tuesday, Apr 21, 2015, 6:30 PM
DLA Piper
555 Mission Street San Francisco, CA
150 Members Went
Come join us for a great evening of Node.js lightning talks plus a slightly longer deep-dive. For those coming straight from work, pizza and drinks will be provided. Video recordings of the talks will posted shortly after the event for those who cannot join us. The evening should have something interesting for both beginners and advanced Node devel...
Check out this Meetup →
Let me know if you do, and I'll connect you to the Organizers!
Neil Craig @neilstuartcraig Mar 13 2015 03:21
Hi guys. I've had zero time this week but the passport plugin looks like it might work. I haven't tested it on a public facing server, I will do but it'll be next week at least before I get time. If anyone wants to test it in the mean time, I'd really appreciate it along with any feedback.
You can find it on GitHub: https://github.com/neilstuartcraig/ah-passport-plugin and/or npm install ah-passport-plugin
Neil Craig @neilstuartcraig Mar 13 2015 06:57
I created a gitter room for the passport plugin to save cluttering this one: https://gitter.im/neilstuartcraig/ah-passport-plugin
Sebastien Stettler @billybonks Mar 14 2015 05:46
hey guys, is there a place where i can find action hero middleware
for example im building an api where for single finds the paths are /{route}/:id, i can write a middle where to proccess the id for easy access, but would rather use one if its already built
Evan Tahler @evantahler Mar 14 2015 08:26
I haven't seen one, but it seems simple enough. You probably can get that functionality from only the router anyway.
http://www.actionherojs.com/docs/servers/web.html#routes
Sebastien Stettler @billybonks Mar 14 2015 09:36
ye that was the plan :smile:, enjoyed your background workers talk btw
Sebastien Stettler @billybonks Mar 14 2015 09:49
is the parameter is already processed :smile: params: { id: '1', action: 'GetProduct', apiVersion: 1 },
Evan Tahler @evantahler Mar 14 2015 09:58
Should be, if you configure both the route and action.
Sebastien Stettler @billybonks Mar 14 2015 23:45
i notice that form data isnt being processed the same way as it is in this example http://www.actionherojs.com/docs/servers/web.html#uploaderjs-action
my connection.params returns { action: 'UploadProducts', apiVersion: 1 }
and my connection.rawConnection.params returns
query: {},
body: { key1: 'sssqq' },
files:
{ file1:
{ domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
size: 413465,
path: '/tmp/upload_d660ee38727036e7d9d4d83f21fc50c3',
name: 'ember-data.js',
type: 'text/javascript',
hash: null,
lastModifiedDate: Sun Mar 15 2015 14:44:02 GMT+0800 (SGT),
_writeStream: [Object] } } }
Evan Tahler @evantahler Mar 15 2015 04:04
Ahh! that example hadn't updated the syntax for params. Updated here evantahler/actionhero@caa25d6
all good now @billybonks
Sebastien Stettler @billybonks Mar 15 2015 04:40
ye works now thanks
Chad Robinson @crrobinson14 Mar 16 2015 09:02
Hey all, just wanted to say that our latest ActionHero project just went into production! (Won't be our last.) We're announcing this later this week at SXSW, but here's a URL if anybody wants a sneak-peek. http://www.firetalk.com/
Evan Tahler @evantahler Mar 16 2015 09:54
Nice!
Chad Robinson @crrobinson14 Mar 16 2015 10:01
It's still a little rough. If anybody is curious, we'll have a bunch of guest hosts online streaming at 3pm EST today.
Products/services used: ActionHero, SequelizeJS, AngularJS, Wowza, Auth0, Uploadcare, maybe a few I'm forgetting. Lots of Kibana analytics and other tools.
I will be wearing the ActionHero T-Shirt this week at SXSW. ;)
Neil Craig @neilstuartcraig Mar 16 2015 10:20
Looks cool. I'll try to have a proper look later when I'm home.
Just checking it in my iPhone, might be good to add the iOS scroll CSS attributes if that won't mess other things up
Evan Tahler @evantahler Mar 16 2015 10:57
oh man! send a photo of you in the shirt at SXSW!
Greg Coonrod @gcoonrod Mar 16 2015 11:06
My first PR for an open source project got merged! I'm psyched that I get to be involved with the AH community. Thanks @evantahler.
Evan Tahler @evantahler Mar 16 2015 11:08
Welcome to the team!
Chad Robinson @crrobinson14 Mar 16 2015 11:24
@neilstuartcraig Yeah, we haven't added mobile support. I know it sounds stupid not being mobile-first these days but this is an RTMP streaming service. iOS and Flash aren't friends. We have to do server-side transcoding to support it, and we really want to focus on MVP for a few weeks. It's coming soon.
@evantahler I will!
@gcoonrod Thanks for your contribution!
Greg Coonrod @gcoonrod Mar 16 2015 11:32
Is there a best practice for organizing actions to coincide with REST endpoints? For example, If I have /api/users as an endpoint should I create a seperate action JS file for each of the CRUD actions or is it more common to create one users action file and put 4 actions in that file?
Chad Robinson @crrobinson14 Mar 16 2015 12:19
We went with one action per file. It just was a lot easier to keep track of. We named the files the same as the action name.
I mean, if you share a lot of code I can see combining but it's a very personal architectural choice. Only you can really know for us.r
*sure
Greg Coonrod @gcoonrod Mar 16 2015 12:20
Good point, thanks for the feedback.;
Chad Robinson @crrobinson14 Mar 16 2015 12:26
We centralized a lot of our functionality in our ORM layer - we're heavily DB-centric in our API. We used SequelizeJS which lets us make custom functions in the model layer.
Neil Craig @neilstuartcraig Mar 16 2015 12:27
I also stick to one action per file. If you're using RBAC or similar, I'd suggest thinking about how you structure your actions in terms of that - to keep your ACL sane and manageable :-)
Chad Robinson @crrobinson14 Mar 16 2015 12:27
So f/i we have an initializer called api.models that contain our DB models. We do something like api.models.channel.getDeepRecord to load a channel record with all business rules and nesting followed. We can call that from all over, whenever we need a full channel record. That made for a lot less code in our actual actions, so there wasn't as much need to split them. Our typical action is around 80 lines or so.
Neil Craig @neilstuartcraig Mar 16 2015 12:28
@ccrobinson14 - understood :-). I just thought I'd mention in case you'd not spotted it yet.
Neil Craig @neilstuartcraig Mar 16 2015 14:22
Hey guys. I am working on a little module (will share soon) which uses HTTP headers. When i look at them (via connection.rawConnection.responseHeaders) i see they’re an array or arrays, e.g.: `[ [ 'Content-Type', 'application/json; charset=utf-8' ],
[ 'X-Powered-By', 'actionhero API' ],
[ 'Access-Control-Allow-Origin', '*' ],
[ 'Access-Control-Allow-Methods',
'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS, TRACE' ],
[ 'Access-Control-Allow-Headers', 'Content-Type' ],
[ 'Cache-Control', 'max-age: 60, public' ] ]'
This is pretty awkward to handle in that I can’t e.g. examine connection.rawConnection.responseHeaders.headerA
I presume there’s a reason that the headers are stored as they are? Would it be painful to change it to an object? That;d be way simpler to deal with (for me anyway)
No stress if not, i’ll write a little loop to go through the array but just wanted to ask as i have come across it
Jason Marmon @jtmarmon Mar 16 2015 14:31
fyi @neilstuartcraig ramda.js provides a great utility function for this: R.fromPairs
http://ramdajs.com/docs/#fromPairs
Neil Craig @neilstuartcraig Mar 16 2015 14:33
Ah cool, thanks @jtmarmon that helps. I guess i’d still like to have the headers as an object for simplicity and speed but I am likely missing a fundamental reason they’re an array :-)
Jason Marmon @jtmarmon Mar 16 2015 14:33
always be evangelizing
me, 2015
Neil Craig @neilstuartcraig Mar 16 2015 14:35
(the next issue will be dealing with the horrible format of the “Cache-Control” header - whoever thought that up should be shot repeatedly…in the metaphorical sense)
Jason Marmon @jtmarmon Mar 16 2015 14:38
you can write him an angry email here http://roy.gbiv.com/
Neil Craig @neilstuartcraig Mar 16 2015 14:41
I think the styling on his website says it all . Seriously though, i guess it was probably 1993 or something. Still, that format…yuck
Evan Tahler @evantahler Mar 17 2015 02:27
Ha
Hey @neilstuartcraig feel free to change the headers to a hash! I don't know what I did it that way...
Neil Craig @neilstuartcraig Mar 17 2015 02:38
Cool, thanks @evantahler. I'll create a
PR when I get a moment
I guess this might break code for folk though.
Is there any interest in me adding some convenience methods e.g setHeader() or similar?
My use case is mainly in the cache-control header so I'm going to write a small plugin to help with that as the format of that header sucks so badly
Jason Marmon @jtmarmon Mar 17 2015 07:27
is it possible to put subdirectories in /tasks and still have them be run? I'm getting an error which I think is caused by tasks being in subdirectories. if not, is this something you'd take a PR on?
Neil Craig @neilstuartcraig Mar 17 2015 07:28
if it works the same as actions then you need to include the dir name in the task name - havw you tried that?
i’ve not used tasks myself though
Jason Marmon @jtmarmon Mar 17 2015 07:28
you mean the task name should be 'directory/myTask' ?
Neil Craig @neilstuartcraig Mar 17 2015 07:29
yep
that’s how it’s done for actions
worth a quick try at least
Jason Marmon @jtmarmon Mar 17 2015 07:29
hmm. maybe that's new? I have a bunch of actions in subdirectories without including the path and they work just fine
i'm on ah 9.4
Neil Craig @neilstuartcraig Mar 17 2015 07:31
i think the behaviour changed in v9 or 10 to be more strict but i cant remember 100%
Jason Marmon @jtmarmon Mar 17 2015 07:31
got it. i'll try it for tasks
Neil Craig @neilstuartcraig Mar 17 2015 07:31
anyway, just though it was a 1 minute suggestion :-)
cool
it’d be good to document it for both if it’s not already
Jason Marmon @jtmarmon Mar 17 2015 07:34
no dice
Neil Craig @neilstuartcraig Mar 17 2015 07:35
ah crap. It was worth a try.
Jason Marmon @jtmarmon Mar 17 2015 07:35
thanks anyway for the suggestion :D maybe @evantahler has an idea
Neil Craig @neilstuartcraig Mar 17 2015 07:35
it’d be cool if it could/can work that way though - i use that pattern externsively for actions
Jason Marmon @jtmarmon Mar 17 2015 07:36
i don't really like that structure tbh. I think action names should be independent of the directory structure and instead enforced as convention if that's something you want
Neil Craig @neilstuartcraig Mar 17 2015 07:37
I was more meaning segregation of actions into dirs…but i do like explicitly naming actions, that way if they get moved they won’t be easily lost
Jason Marmon @jtmarmon Mar 17 2015 07:37
well yeah I do segregate all of my actions into subdirectories, but I don't think that should impact their names imo
Neil Craig @neilstuartcraig Mar 17 2015 07:38
i quite like it as i say, also good if programatically acessing the actions - like in the ACL i wrote
easy to use the name as an RBAC/ACL namespace grouping
Jason Marmon @jtmarmon Mar 17 2015 07:40
yeah that's fine if it works well for you, I just don't think it makes sense as something enforced actionhero. i don't think enforcing arbitrary convention is very much in the spirit of the framework, although evan might disagree
Neil Craig @neilstuartcraig Mar 17 2015 07:43
i guess the best of both worlds would be to allow either the short or long form matches
Jason Marmon @jtmarmon Mar 17 2015 07:45
well if that's the convention you want, why not just write 'subdirectory/taskName' when you address the action in config/routes.js. i still don't think it makes sense to put the subdir in the action name though, but maybe you could create another property in the metadata of your action called 'group' or something and write an initializer that goes through all subdirectories and makes sure the 'group' property of the action matches its directory
and then make it a plugin :3
you could also enforce the action name thing in an initializer by splitting with '/' as the delimiter. i'm just not of the opinion that you should mix those two :stuck_out_tongue_closed_eyes:
Neil Craig @neilstuartcraig Mar 17 2015 07:46
it works fine right now so i’m happy TBH :-) I don’t actually use defined routes, i just rely on the default behaviour which works well for me
Jason Marmon @jtmarmon Mar 17 2015 07:47
ahh. now i see why you did it that way. you're using it for routing. makes sense
Neil Craig @neilstuartcraig Mar 17 2015 07:48
yep, i am indeed :-)
Jason Marmon @jtmarmon Mar 17 2015 07:48
ANYWHO back to my original point @evantahler is there any way I can have subdirectories in tasks
Jason Marmon @jtmarmon Mar 17 2015 08:03
odd...it looks like it is loading directories recursively just as actions are loaded recursivesly
api.config.general.paths.task.forEach(function(p){ api.utils.recursiveDirectoryGlob(p).forEach(function(f){ api.tasks.loadFile(f); }); })
so i'm not sure why it's giving me issues. time for some debuggin
Jason Marmon @jtmarmon Mar 17 2015 08:13
oh interesting. so for an unrelated reason (mistake in my task) the task loader throws an error. but for some reason the variable task is undefined in the catch on line 39 of initializers/tasks even though task is not undefined in the try portion
how odd
either way my issue is fixed...just curious why that variable disappears
Jason Marmon @jtmarmon Mar 17 2015 10:31
also @evantahler - i was wondering why you convert resque timestamps to seconds from milliseconds (https://github.com/taskrabbit/node-resque/blob/master/lib/queue.js#L79). is it just because resque can only be accurate in running tasks on a per-second basis?
Evan Tahler @evantahler Mar 17 2015 10:34
1) sub-directories for tasks (just like actions) should work OK
2) resque, the spec, works in seconds... that's just how it is
and remember those timestamps are when it is OK to work the job, not actually when the job will be worked
so having a 1s resoltion seems OK to me
@jtmarmon can you explain that issue better?
like 39... something?
Jason Marmon @jtmarmon Mar 17 2015 10:47
This message was deleted
got it. yeah was just curious.
and sure - the issue I had was that one of the requires was incorrectly written, so it was throwing an error in the module. this error is caught by this try/catch https://github.com/evantahler/actionhero/blob/v11.0.0/initializers/tasks.js#L23. however, the error I received was Cannot read property 'name' of undefined coming from here https://github.com/evantahler/actionhero/blob/v11.0.0/initializers/tasks.js#L34
so for some reason the task was becoming undefined. no idea why that would be since it was an object when I logged it in the try portion
Ankur Kaushal @ankurkaushal Mar 18 2015 08:33
Is there a way to check the payload client is sending in? I have some optional parameters in an API call, and I want to update only ones that user is sending in.
I believe I can use connection.params but just want to be sure
Moreover is there a way to display showing server information & requester information?
*disable
Ankur Kaushal @ankurkaushal Mar 18 2015 08:41
Never found the answer to my second question.
Turns out you can set the options to false in metadataOptions
In web.js
Greg Coonrod @gcoonrod Mar 18 2015 09:34
I'm working on a AH plugin and I'd like to append new routes to the existing config/routes.js. Is there a recommended way to achieve this?
Sebastien Stettler @billybonks Mar 18 2015 09:35
This message was deleted
Jason Marmon @jtmarmon Mar 18 2015 09:36
@gcoonrod api.config.routes
Sebastien Stettler @billybonks Mar 18 2015 09:37
@ankurkaushal connection.rawConnection.params, connection.params will give you parsed params
Greg Coonrod @gcoonrod Mar 18 2015 09:37
@jtmarmon So I can just append my new routes to that object?
Jason Marmon @jtmarmon Mar 18 2015 09:38
you can in an initializer. i believe it'd be a bit more complicated to do after initializers/routes.js runs (i.e. after the server boots)
Greg Coonrod @gcoonrod Mar 18 2015 09:41
Can I use api.routes.registerRoute after boot to add new routes on demand?
Jason Marmon @jtmarmon Mar 18 2015 09:43
probably? give it a shot
Chad Robinson @crrobinson14 Mar 18 2015 10:30
Has anybody done any benchmarking in the WebSocket layer? I'm noticing that API calls made through there are MUCH slower. We have a relatively simple database "get" call that we make a lot and I was trying to figure out why it was reporting taking 200-400ms on average. After some analysis, I noticed that I was averaging 18-23ms through straight HTTP requests.
I don't believe the WebSocket is actually "slow" - I'm wondering if there's an async component in there somewhere waiting more than it needs to.
I'm going to do some tracing but wanted to ping the group and see if anybody had seen the same thing and/or had ideas.
Ankur Kaushal @ankurkaushal Mar 18 2015 10:53
I defined a route like this "/user/:id" but when I try to do this, /user/10 it gives me invalid action
The ":id" would have to be defied inside inputs right?
Also what I might be missing?
Chad Robinson @crrobinson14 Mar 18 2015 10:55
Paste your route config entry and your inputs config block
Ankur Kaushal @ankurkaushal Mar 18 2015 10:56
inputs : { id : { required : true, formatter: function(s){ return String(s); } }, tagName: { //TODO: move the validators to a separate file validator : function(param){ if (param.length > 20 && regexTest.test(param)) { return new Error('Tag Name Error.'); } else { return true; } } }, tagDesc: { validator : function(param){ if (param.length > 40) { return new Error('Tag description length excedded.'); } else { return true; } } } },
Chad Robinson @crrobinson14 Mar 18 2015 10:57
ok and the route entry?
Ankur Kaushal @ankurkaushal Mar 18 2015 10:57
Route config:
``` post: [
{ path:"/createTag", action:"createTag" },
{ path:"/updateTag/:id", action:"updateTag"}
],```
Chad Robinson @crrobinson14 Mar 18 2015 10:58
And just to be clear you're accessing this with a POST to /user/10?
Well, to /api/user/10 or whatever the API endpoint is for you?
Ankur Kaushal @ankurkaushal Mar 18 2015 10:59
Yes, like /updateTag/10?tagName=something
":id" has to be defined inside inputs right?
Chad Robinson @crrobinson14 Mar 18 2015 11:01
Yes, just like you did it
Ankur Kaushal @ankurkaushal Mar 18 2015 11:01
But why server is giving me an invalid action error?
Chad Robinson @crrobinson14 Mar 18 2015 11:01
Here is an exact copy of the metadata for one of my actions
var action = { name: 'updateChannel', description: 'Update an existing channel. Only owners or producers of the channel may call this method.', requireUser: true, blockedConnectionTypes: [], firetalkOptions: { group: 'Channels' }, inputs: { channel: { required: true }, updateTags: { required: false } } };
Boy that pastes badly.
Check the obvious stupid stuff, like action name. It's case sensitive in both spots, and have to match
And confirm the precise error message you're getting?
Is it "unknown action or invalid apiVersion" or something else?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:02
"Error: unknown action or invalid apiVersion"
Jason Marmon @jtmarmon Mar 18 2015 11:03
are you adding /api in front of the path
Ankur Kaushal @ankurkaushal Mar 18 2015 11:03
yes, indeed I am
It's like this http://localhost:8080/api/updateTag/55084ac3222965f74dcfeb73?tagName=bigmac
Jason Marmon @jtmarmon Mar 18 2015 11:05
you're such the action name is 'updateTag'? can i see its metadata
Ankur Kaushal @ankurkaushal Mar 18 2015 11:05
{
"error": "Error: unknown action or invalid apiVersion",
"serverInformation": {
"serverName": "actionhero API",
"apiVersion": "0.0.1",
"requestDuration": 1,
"currentTime": 1426701873065
},
"requesterInformation": {
"id": "1817481418de319542784f20cf390207b6ea5947-618e7f3d-ea42-423e-8b62-495f82e60755",
"fingerprint": "1817481418de319542784f20cf390207b6ea5947",
"remoteIP": "127.0.0.1",
"receivedParams": {
"tagName": "bigmac"
}
}
}
Jason Marmon @jtmarmon Mar 18 2015 11:06
no the .js file
Ankur Kaushal @ankurkaushal Mar 18 2015 11:06
Actions?
Chad Robinson @crrobinson14 Mar 18 2015 11:06
He wants the top of your action file
Not the inputs, the whole block
Ankur Kaushal @ankurkaushal Mar 18 2015 11:06
exports.updateTag = {
name: 'updateTag',
description: 'I update the existing tags',
inputs : {
id : {
required : true,
formatter: function(s){ return String(s); }
},
tagName: {
//TODO: move the validators to a separate file
validator : function(param){
if (param.length > 20 && regexTest.test(param)) {
return new Error('Tag Name Error.');
} else {
return true;
}
}
},
tagDesc: {
validator : function(param){
if (param.length > 40) {
return new Error('Tag description length excedded.');
} else {
return true;
}
}
}
},
run: function(api, connection, next){
tagsTable.updateTag(api, function(error, response){
// if (error) {
// connection.response.error = 'Error updating tag';
// }
// if (response === 1) {
// connection.response.data = 'Tag has been updated';
// }
console.log(connection.params)
next(connection, true);
}, {tagParams: connection.params})
}
}
tagsTable
Jason Marmon @jtmarmon Mar 18 2015 11:07
i think you need to change exports.updateTag to exports.action (at least that's how i do it)
Chad Robinson @crrobinson14 Mar 18 2015 11:07
I don't set exports.tagname, I set exports.tag
Right, what he said
All modules export "action".
Ankur Kaushal @ankurkaushal Mar 18 2015 11:08
Let me try
No change
but when I remove ":id", it works fine
Chad Robinson @crrobinson14 Mar 18 2015 11:10
Remove it from where?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:11
Routes file
Now it looks like this path:"/updateTag", action:"updateTag"
But it is weird that it isn't working with this
path:"/updateTag/:id", action:"updateTag"
Jason Marmon @jtmarmon Mar 18 2015 11:12
i think maybe the input from your path is conflicting with the input in your route. not sure because i haven't upgrades to ah 10 yet
Chad Robinson @crrobinson14 Mar 18 2015 11:12
Try renaming the parameter to something other than "id".
Ankur Kaushal @ankurkaushal Mar 18 2015 11:13
let's do that
nope still same error
inputs : {
tagID : {
required : true,
formatter: function(s){ return String(s); }
},
tagName: {
//TODO: move the validators to a separate file
validator : function(param){
if (param.length > 20 && regexTest.test(param)) {
return new Error('Tag Name Error.');
} else {
return true;
}
}
},
tagDesc: {
validator : function(param){
if (param.length > 40) {
return new Error('Tag description length excedded.');
} else {
return true;
}
}
}
},
Route.js
post: [
{ path:"/updateTag/:tagID", action:"updateTag"},
],
Chad Robinson @crrobinson14 Mar 18 2015 11:14
As a test, if you have query routing enabled, try ?action=updateTag&tagId=XYZ&tagName=test
The code that fires this error is fairly simple, but checks TWO things so we need to figure out which is failing:
} else if(!self.connection.action || !self.actionTemplate){ api.stats.increment('actions:actionsNotFound'); if(self.connection.action === '' || !self.connection.action){ self.connection.action = '{no action}'; } self.completeAction('unknown_action');
Why does this thing always paste so badly?
Oh
} else if(!self.connection.action || !self.actionTemplate){ api.stats.increment('actions:actionsNotFound'); if(self.connection.action === '' || !self.connection.action){ self.connection.action = '{no action}'; } self.completeAction('unknown_action');
Nope
} else if(!self.connection.action || !self.actionTemplate){
api.stats.increment('actions:actionsNotFound');
if(self.connection.action === '' || !self.connection.action){ self.connection.action = '{no action}'; }
self.completeAction('unknown_action');
Needs a newline I guess
Anyway, it fires if either condition is true, so either action is not being parsed correctly from the incoming request, or the action template matching it wasn't found.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:16
let me try
So I did this, http://localhost:8080/api/action=updateTag?tagID=55084ac3222965f74dcfeb73&tagDesc=ankur
it gave me same error
Chad Robinson @crrobinson14 Mar 18 2015 11:18
No, http://localhost:8080/api?action=updateTag&tagID=55084ac3222965f74dcfeb73&tagDesc=ankur
Move the ?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:18
BTW I removed :id part from the route beforehand
With ":id" in the route it works too
Chad Robinson @crrobinson14 Mar 18 2015 11:20
OK, the thing that does this checking is api.routes.matchURL
So you're saying that the URL I pasted above does work, right? That's important.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:20
yep
Chad Robinson @crrobinson14 Mar 18 2015 11:20
OK good, then we can rule out the action definition and focus on the router.
That method above bypasses the router
Is what you have above actually a valid sample tagid?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:21
oh, where I should I look at now?
yes
Chad Robinson @crrobinson14 Mar 18 2015 11:21
Like, the tag IDs can't contain / right?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:21
nope
Chad Robinson @crrobinson14 Mar 18 2015 11:21
Or :
Ankur Kaushal @ankurkaushal Mar 18 2015 11:22
nope
It's actually generated by mongo db
Chad Robinson @crrobinson14 Mar 18 2015 11:22
Right, I figured. Just confirming
You don't have any routes defined under "all" do you?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:23
not at all
Chad Robinson @crrobinson14 Mar 18 2015 11:24
Do you have simpleRouting enabled in config/servers/web.js (or not defined? - the default is true)
Ankur Kaushal @ankurkaushal Mar 18 2015 11:24
Yes, simpleRouting is true
Chad Robinson @crrobinson14 Mar 18 2015 11:25
Running out of things to try here. I SUSPECT something is conflicting between your use of path-based and query-based params. I haven't read this part of the code before so I'm just poking through obvious things.
In my posts I don't use query params. I specify them in the POST BODY.
So I do like /api/updateTag/1
And the body would contain something like tagName=test
I wonder if your use of query params is triggering something in AH that changes how it parses the incoming request
Ankur Kaushal @ankurkaushal Mar 18 2015 11:26
I was just testing out stuff
http://localhost:8080/api/updateTag/55084ac3222965f74dcfeb73?tagName=mac
Chad Robinson @crrobinson14 Mar 18 2015 11:27
Suggestion: add some console.logs in node_modules/actionhero/initializers/routes.js in api.routes.matchURL and api.routes.processRoute
See how it's parsing the path.
These functions get called to parse incoming requests from Web.
In web.js when it goes to process the request it has a hefty code block commented "// API"
It parses the query params, then does something weird. It checks the incoming method.
If it's not a GET, it calls the form processor which I think parses the body -0 haven't looked.
GETs don't have bodies.
Well, not normally.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:29
so you're telling I should move my stuff to get?
*GET
Chad Robinson @crrobinson14 Mar 18 2015 11:29
No
I'm suggesting you move tagName to the body
Instead of the URL
Jason Marmon @jtmarmon Mar 18 2015 11:30
actionhero is magic
Chad Robinson @crrobinson14 Mar 18 2015 11:30
That's the standard for POST anyway
Ankur Kaushal @ankurkaushal Mar 18 2015 11:30
like this updateTag/id/tagName?
Chad Robinson @crrobinson14 Mar 18 2015 11:30
No
updateTag/id
BODY:
tagName=newname
Like this:
$http('/api/updateTag/123', { tagName: 'newname' })...
That would be for AngularJS.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:34
I did a curl actually
and it worked
curl -X POST -d '{tagName:"mac"}' http://localhost:8080/api/updateTag/55084ac3222965f74dcfeb73
Follow Up question, I have two more fields which are not required. But I am having an issue where I update the other field and it sets the other field as null.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:40
like I have tagName and tagDesc. And If I just update tagName, it sets tagDesc as null
So is there any method, which I can use to update only the params that are coming in?
Or do I have to use if-else to handle that?
Chad Robinson @crrobinson14 Mar 18 2015 11:42
ActionHero doesn't do database work and that sounds like something in your ORM. What are you using?
SequelizeJS will only do that if you actually define the field and set it to null.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:42
MongoDB
Chad Robinson @crrobinson14 Mar 18 2015 11:43
Maybe set up a validator/formatter to return undefined in those cases?
Ankur Kaushal @ankurkaushal Mar 18 2015 11:44
So eventually I would have to use if else then
Chad Robinson @crrobinson14 Mar 18 2015 11:44
Impossible to know without knowing how you're calling your DB and what you're passing to it.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:48
this what I was doing initially:
// api.mongo.db.collection('tags').update({"_id" : ObjectId(tagParams._id)}, {tagName: tagParams.tagName, tagDesc: tagParams.tagDesc}, function(err, res){
// if (err){
// callback(err, null);
// } else {
// callback(null, res);
// }
// });
please ignore //
Chad Robinson @crrobinson14 Mar 18 2015 11:54
You're passing in both args whether they're provided to your API call or not, which makes sense that it would null out the one not provided (since null is an acceptable and useful database concept). In fact, you're basically doing the thing you DO if you WANT to null a field.
Why not just pass in connection.params?
There's risk in that if you aren't careful about sanitization, FYI.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:55
yeah I have to take care of that as well
Chad Robinson @crrobinson14 Mar 18 2015 11:55
This is where an ORM like CaminteJS or SequelizeJS is helpful. They add all that "sugar" for doing database work that really isn't the framework's main job.
Ankur Kaushal @ankurkaushal Mar 18 2015 11:56
ahh at this stage I don't really want to deal with another lib or framework
But here's the thing though. Connection.params contains tag id as well
Chad Robinson @crrobinson14 Mar 18 2015 12:01
That wouldn't cause a problem because Mongo doesn't allow you to null out the object ID. You can't even change it to another valid value. It ignores attempts to do so.
But again, this is all Mongo-related, not ActionHero. You're going to get better advice from a Mongo community forum past this point.
Ankur Kaushal @ankurkaushal Mar 18 2015 12:02
Oh okay
Evan Tahler @evantahler Mar 18 2015 12:10
Thanks for sorting that out @crrobinson14 !
Ankur Kaushal @ankurkaushal Mar 18 2015 12:11
Oh yeah I forgot to say thanks as well!
Evan Tahler @evantahler Mar 18 2015 12:11
@gcoonrod yep, registerRoute is fair game
(or you can just mess with the hash, either way)
no prommisies on not breaking either in a later version though
@crrobinson14 so I made this super aswesome websocket load test: https://github.com/evantahler/actionhero/blob/master/public/websocketLoadTest.html
ya'll can play with it and break my free heroku servers here: http://demo.actionherojs.com/public/websocketLoadTest.html
(note that heroku's routers limit you to ~5 connections/client)
but I can get something like 1500 clients/sec on my laptop
er req/sec
where req/sec = action/sec
Chad Robinson @crrobinson14 Mar 18 2015 12:15
Thanks, @evantahler I will look at that. I think you mentioned it before but I forgot the link.
But see the thing is, I'm fairly certain iut's not a PERFORMANCE issue.
Evan Tahler @evantahler Mar 18 2015 12:16
on a related note, master is deployed automatically to that server, so ya'll can always play with the latest and greatest
Chad Robinson @crrobinson14 Mar 18 2015 12:16
I sprinkled console.log statements all over the place in my code and ActionHero itself. The entire internal process takes only a millisecond or two longer than the action. Very little overhead.
ok cool.
Evan Tahler @evantahler Mar 18 2015 12:16
well, you can now compare that website to apache bench (or similar)
Chad Robinson @crrobinson14 Mar 18 2015 12:16
The delay comes in right at the last minute in sendMessage.
Evan Tahler @evantahler Mar 18 2015 12:17
wacky. well, let me know what you learn!
could be in primus, we could be JSON.parse-ing too many times... could be lots of stuff
Chad Robinson @crrobinson14 Mar 18 2015 12:18
Very crude, but check this out
before actionDomain.run 1426706262269 running action 1426706262269 done preprocessing 1426706262270 a: 17ms done running 1426706262287 done postprocessing 1426706262287 getChannel
Oops
Evan Tahler @evantahler Mar 18 2015 12:18
also, this thread has a ton of notes about how to benchmark evantahler/actionhero#366
Chad Robinson @crrobinson14 Mar 18 2015 12:18
before actionDomain.run 1426706262269
running action 1426706262269
done preprocessing 1426706262270
a: 17ms
done running 1426706262287
done postprocessing 1426706262287 getChannel
So my action took 17ms to execute start/finish and actionhero was only another 1ms start/finish
Sounds great, right?
But the result didn't get to my browser for another 127ms
Evan Tahler @evantahler Mar 18 2015 12:19
and it's a local server?
no network involved?
Chad Robinson @crrobinson14 Mar 18 2015 12:19
With a straight XHR request the entire thing is done in like 19ms client->server->client
Right.
All localhost
Evan Tahler @evantahler Mar 18 2015 12:19
wierd
Chad Robinson @crrobinson14 Mar 18 2015 12:19
It's likeit's in Primus somewhere
Evan Tahler @evantahler Mar 18 2015 12:19
I've got to run, but open an issue for it
Chad Robinson @crrobinson14 Mar 18 2015 12:19
That "done postprocessing" I stuck in sendmessage
Right before rawConnection.write
OK, thanks.
Jason Marmon @jtmarmon Mar 18 2015 12:53
anyone know why actionhero.actionheroPrototype.start just randomly stopped invoking the callback in my tests today? can't deploy o_O
we need a /giphy in here
/giphy sad
literally nothing has changed in any code that touches that between when my tests were passing and failing
so i'm a little lost
and this is on CI so it's a clean build
"actionhero": "^9.4.1"
Evan Tahler @evantahler Mar 18 2015 12:58
Check your initializers (like connecting to a db or something) Run in debug for more info
Jason Marmon @jtmarmon Mar 18 2015 12:59
when i turn off logger silencing and run the tests all the initializers succeed and the server manages to start up. also when i just do npm start and run in development the server works fine
I do get
2015-03-18 15:59:17 - notice: webSockets bound to 0.0.0.0:18080
2015-03-18 15:59:17 - warning: loading the testServer
i've never noticed that warning before so i don't know if it's regular
Jason Marmon @jtmarmon Mar 18 2015 13:13
WOO alright i got it. one of my _starts was failing which explains why i saw the server booting but cb not being passed back
omichowdhury @omichowdhury Mar 18 2015 13:45
anyone going to the NYC node.js meetup tonight, will be repping my AH tshirt
Ankur Kaushal @ankurkaushal Mar 19 2015 07:09
Looks like I have one more issue, I have to restart my server everytime I make a small change to any of files. What could be the reason?
Also I have to use sudo to start the server.
Greg Coonrod @gcoonrod Mar 19 2015 07:25
@omichowdhury How was the node meetup? Did you rep AH for us?
Chad Robinson @crrobinson14 Mar 19 2015 08:05
I'll be wearing it tomorrow or Sat at SXSW live streaming with Rachel Ray! (Although I seriously doubt they'll put ME on cam - I'm not the star.)
Evan Tahler @evantahler Mar 19 2015 08:48
Ank: how did you install node? Shouldn't ever need to use Sudo
good luck with the fame!
Eric Mey @ericmey Mar 19 2015 14:42
I have been playing all day with a way to get newrelic installed correctly in a my actionhero application. My problem is that it really needs to be at the start of the actionhero.js file to log all redis calls and not throw an error on NewRelic.com. My first attempt at a solution was to change the loadPriority/startPriority/stopPriority in the initializer, but that unfortunately did not work. I also thought I had a brilliant plan to put a shell script in my npm postinstall to insert it, which works locally, but unfortunately my deployment server (AWS Elastic Beanstalk) does not support postinstall properly. Evan, I know you have written a plugin for newrelic... how do you deal with this situation? Thanks in advance.
omichowdhury @omichowdhury Mar 19 2015 17:33
@ericmey When we used newrelic we just lived with the notices about redis. Didn't seem to affect or skew the data and I never felt like I needed more visibility into redis since it was never the bottleneck.
@ericmey you may also find this helpful https://gist.github.com/omichowdhury/027c94c46c3d9c40a1c9
Evan Tahler @evantahler Mar 20 2015 08:47
Play with the difference between start and init in your initializers. Also the priority levels. You CAN be the first thing loaded if you need
Chad Robinson @crrobinson14 Mar 20 2015 08:50
@ericmey We went through the same thing as you. We found that adding the require() for N/R at the top of the CONFIG files helped a lot - it got rid of one of the two notices.
The config files are loaded/run very early.
We tracked the other notice (one was MySQL, one for Redis - can't remember which) down to a bug in NewRelic's agent in how they determine whether a module was loaded too early.
@evantahler You may also want to know this. NewRelic looks through the NodeJS require cache to determine if a module was loaded, and the alert comes literally from an if/then on the NAME of the module loaded.
The config files are NAMED redis.js, mysql.js, etc.
N/R doesn't check path or anything else.
There's no way to address this in ActionHero land but a hack/work-0around that seems to help is renaming the config files to something like mysqlCfg.js. It's annoying but...
Somebody should file a ticket with NewRelic for it - we never got a chance to. (We ripped N/R out and went with Kibana on our own servers for cost and flexibility reasons.)
This is why the reporting works despite the complaint. When you don't load N/R before the module it needs to instrument, their reporting does NOT work. So it's a false alarm.
Ankur Kaushal @ankurkaushal Mar 20 2015 10:06
Having an issue again, I just keep getting "error": "Error", back
What might be the possible cause of this?
Ankur Kaushal @ankurkaushal Mar 20 2015 11:00
Seems like I was having issues with inputs
Evan Tahler @evantahler Mar 20 2015 11:59
Heh, yeah. I don't use new relic any more either (got too expensive). But those are the hacks you need I gues :/
Chad Robinson @crrobinson14 Mar 20 2015 12:32
Hey guys, I seem to recall there's a way to run an action from the command line but can't remember where I saw it referenced.
I'm about to roll my own emergency tools to fix some issues / bugs but this would save some time.
Is there a way or did I mis-remember that?
Ankur Kaushal @ankurkaushal Mar 20 2015 12:54
Actionhero needs to provide more detailed error when there's something wrong with the validator
It's giving me "error": "Error", when I do this for one of my inputs
tags : {
validator : function(param){
if ((param.constructor === Array) === false){
throw new Error('Please provide an Array');
}
}
}
Evan Tahler @evantahler Mar 20 2015 13:55
Provide a pull request with fixes! Those action options are new!
Ankur Kaushal @ankurkaushal Mar 20 2015 13:56
Which options?
Eric Mey @ericmey Mar 20 2015 14:20
@omichowdhury @crrobinson14 Thank you for the feedback. I am going to try both of your solutions. @omichowdhury I appreciate the plugin code for the tasks, I have a bug I am trying to track down with mongoose in one of my periodic tasks and that should help me immensely. @evantahler I hear you on the price, they cut me a deal but its still more expensive than all my AWS and Compose hosting put together. Time will tell if its worth it or not... but for now I am in a 1 year contract. :smile:
Neil Craig @neilstuartcraig Mar 20 2015 14:28
Hey guys. Is anyone using the AH client via requireJS? I am not having much success currently - probably doing somethign stupid as i’ve not used it for a couple of years
Neil Craig @neilstuartcraig Mar 20 2015 14:35
or indeed, does anyone have any recommendations for a “better” module loader? i’m not dead-set on requirejs
Sebastien Stettler @billybonks Mar 21 2015 09:21
anyone have experience using AH on google cloud
?
Sebastien Stettler @billybonks Mar 21 2015 11:46
if i define my input like this
inputs: {
email: {optional: false},
password: {optional: false}
},
why does it not throw an error if params are missing form post or get
can understand get but not post
and is there a way for ah to throw an error if undefined inputs are sent to the server ?
Evan Tahler @evantahler Mar 21 2015 13:48
Billy that should return an error to the client, but not throw in the server sense
Sebastien Stettler @billybonks Mar 22 2015 08:42
how do i overwrite the modifications added to my response in servers/web.js
Evan Tahler @evantahler Mar 22 2015 11:39
Not really sure what you are asking. You shouldn't touch the servers unless you are making a new transport.
Ankur Kaushal @ankurkaushal Mar 23 2015 12:22
Turns out I can't put arrays in the query string
Server gives an error everytime I try to do that
Ankur Kaushal @ankurkaushal Mar 23 2015 12:40
On that note, can I process arrays in the query string?
Sebastien Stettler @billybonks Mar 24 2015 06:20
@evantahler im basically trying to not send this extra information for every request as i dont need it
"serverInformation": {
"serverName": "actionhero API",
"apiVersion": "0.0.1",
"requestDuration": 1,
"currentTime": 1427203131174
},
"requesterInformation": {
"id": "d892e4677bb96f9e0ac5ef350ef13fe249f05b99-1ed73f21-7b6b-4519-8cbe-0a5c4d3e02ad",
"fingerprint": "d892e4677bb96f9e0ac5ef350ef13fe249f05b99",
"remoteIP": "127.0.0.1",
"receivedParams": {
"action": "register",
"apiVersion": 1
}
Ankur Kaushal @ankurkaushal Mar 24 2015 06:20
@billybonks You can disable it
In web.js, make both properties false:
metadataOptions: {
serverInformation: true,
requesterInformation: true
},
But in if you're in prod, it will not be shown
Sebastien Stettler @billybonks Mar 24 2015 06:22
@ankurkaushal thanks :+1:
Ankur Kaushal @ankurkaushal Mar 24 2015 06:22
you're welcome!
Sebastien Stettler @billybonks Mar 24 2015 06:22
you solved your array issue ?
Ankur Kaushal @ankurkaushal Mar 24 2015 06:22
Query params one?
Sebastien Stettler @billybonks Mar 24 2015 06:23
ye
Ankur Kaushal @ankurkaushal Mar 24 2015 06:23
seems to be working now
Sebastien Stettler @billybonks Mar 24 2015 06:23
cool
Ankur Kaushal @ankurkaushal Mar 24 2015 06:24
But I have one weird issue, for every minor change I have to restart my server
Sebastien Stettler @billybonks Mar 24 2015 06:27
hmm strange, dont have that issue here. is it running in dev mode ?
Ankur Kaushal @ankurkaushal Mar 24 2015 06:27
yeah
Ankur Kaushal @ankurkaushal Mar 24 2015 06:56
Is anyone using grunt with actionhero?
Evan Tahler @evantahler Mar 24 2015 07:03
there are some grunt tasks that come with actionhero, sure
https://github.com/evantahler/actionhero/tree/master/grunt
but using grunt to run actionhero? nope
@crrobinson14 I just updated to primus v3 in master. They promise all sorts of improvments. Try your ws benchmarks against the master branch.
how was SXSW?
Ankur Kaushal @ankurkaushal Mar 24 2015 07:04
My main objective is to watch all action files and some files in my libs folder
and then if change happens restart server
currently I have restart my server manually
Evan Tahler @evantahler Mar 24 2015 08:09
@ankurkaushal that's totally how developerMode should work now... we even test for it: https://github.com/evantahler/actionhero/blob/master/test/core/developerMode.js Are you on windows? That (and a few other things) don't work on windows
Ankur Kaushal @ankurkaushal Mar 24 2015 08:10
No I am on Mac
Evan Tahler @evantahler Mar 24 2015 08:10
that's good
Ankur Kaushal @ankurkaushal Mar 24 2015 08:10
but that restarting on every change is such a pain
Evan Tahler @evantahler Mar 24 2015 08:11
put your logger in debug mode
you'll get lines like this:
2015-03-24 15:11:02 - debug: action (re)loaded: cacheTest @ v1, /Users/evantahler/Dropbox/Projects/actionhero/actions/cacheTest.js
when it notices files change
oh, and you need node v.10 or greater
are you seeing those log lines at least?
actionhero will only watch for files in the normal places (actions, tasks, initialzers)
but you can use the builtin methods to watch your libs folder: https://github.com/evantahler/actionhero/blob/master/initializers/configLoader.js#L12-L32
and the callback could include api.restart()
Chad Robinson @crrobinson14 Mar 24 2015 12:01
!(https://www.dropbox.com/s/vgft9g57pfgjjs2/2015-03-20%2017.50.26.jpg?dl=0
)
This message was deleted
Showing the flag, this was in front of the Rachael Ray Feedback house.
@evantahler SXSW went well, although bandwidth was a real struggle. No surprise, but disappointing how bad it was.
I will test out Primus v3. It does seem to be in that layer. It almost feels like it's not even a performance issue, like it's more some kind of built-in delay, like what you get with a slow process.nextTick() implementation in async-land (like one done with a setTimeout(..., 100)). Or like the NAGLE alg in TCP. It's a very consistent delivery delay from the Action response, and on our current hardware we're only (and just barely) measuring 1ms total latency start/to finish processing actions.
So I don't think it's AH itself.
I'll report back when I have more.
Chad Robinson @crrobinson14 Mar 24 2015 12:07
Also, re: the discussion above, I noticed something in our own AH dev cycle. Changes to initializers will make AH do a very visible reload - the whole thing restarts. @ankurkaushal this requires developmentMode: true, in your config/api.js file.
However, changes to actions do NOT appear to cause a reload. They WORK, in that if I edit an action it (generally) uses the latest version I've just saved. But it doesn't reload the whole server. I'm not sure how the watcher works - should dig into that some time.
Evan Tahler @evantahler Mar 24 2015 16:19
Actions and tasks just load in. Initializers are funny because they often wrap things like DB connections. Who knows how to gracefully disconnect... So we reboot!
Chad Robinson @crrobinson14 Mar 24 2015 19:00
Makes sense to me, it just took a bit of getting-used-to.
Evan Tahler @evantahler Mar 25 2015 04:20
nice. and those t-shirts came out OK! I still haven't gotten mine yet :(
@ankurkaushal did you sort out your reload issue?
Ankur Kaushal @ankurkaushal Mar 25 2015 08:01
@evantahler ahh not really, didn't get any time to look into it.
Evan Tahler @evantahler Mar 28 2015 03:52
well, keep us posted! File a bug if you can't get it working @ankurkaushal
@neilstuartcraig Add your passport plugin here! http://www.actionherojs.com/docs/core/plugins.html#published-plugins
Neil Craig @neilstuartcraig Mar 30 2015 02:01
Sorry for the delay, will do @evantahler. I have a fair few plugins now and just finalising another which i think is really cool - more on that once it’s done :-)
Amine Mouafik @kytwb Mar 31 2015 01:27
looks like I missed some activity 'round here :) great to see the community growing!
Evan Tahler @evantahler Mar 31 2015 05:48
@kytwb tell your friends!
Ankur Kaushal @ankurkaushal Mar 31 2015 11:51
For some reason reload issue seems to have resolved itself.
BTW does anyone have experience with file uploads to S3? Do I need a middleware to do that?
Ankur Kaushal @ankurkaushal Mar 31 2015 13:46
Never mind, managed to figure out the issue on my own
But here's the thing, formidable doesn't really uploads the full file, I mean the file gets damaged
I had to use node's fs to read the file
Neil Craig @neilstuartcraig Apr 01 2015 03:53
Hey guys. Any objections to me creating a PR with another generate function - to add plugins. I was thinking this would be nice for people to be able to either use programmatically or in "how to install" instructions for plugins.
Sebastien Stettler @billybonks Apr 01 2015 07:43
add the pr will take a look at what u mean
Neil Craig @neilstuartcraig Apr 01 2015 10:12
I can certainly do that but since I've not written it, I didn't want to code it if people deem it inappropriate.
Sebastien Stettler @billybonks Apr 01 2015 10:13
Maybe make a more detailed rfc, if how it would work
Neil Craig @neilstuartcraig Apr 01 2015 10:21
It'd be just like the generate --plugins I added a little while back. A flag in the ah "binary". I'll take a look later and see how much code it is. Might just out it together.
jamesmr89 @jamesmr89 Apr 03 2015 11:11
Quick question, quite new to actionhero, but loving the self documenting setup. I'm wondering if its possible to add a description or example object to the inputs so I can save myself having to document that outside of my actions?
Evan Tahler @evantahler Apr 03 2015 14:55
Add a pull request! There's no reason we can't have a documentation or note attribute on each para
param/input
Evan Tahler @evantahler Apr 04 2015 15:47
@crrobinson14 et al: I took a stab at doing evantahler/actionhero#570 myself via evantahler/actionhero#625. Please check it out!
Neil Craig @neilstuartcraig Apr 05 2015 22:33
Hi @evantahler, @crrobinson14 and everyone else.
I had a really quick look and will check it out properly asap. I'm a little concerned at how middleware is assigned to actions or global. I think this is going to be a bit awkward for some of my uses cases. I'll let you know my feedback as soon as I can.
Also working on a small feature addition as per above. Nearly done on that now.
Evan Tahler @evantahler Apr 06 2015 01:05
@neilstuartcraig how does it become awkward? All middleware is global currently, so this adds the option not to be
Neil Craig @neilstuartcraig Apr 06 2015 01:08
I need to check it out properly but it looked at first glance to be a little tricky to have done middleware global and some per action. That'd be ideal if possible.
I realise that's not how things are now but it'd be great if it could be that way.
I'd see things like parameter normalisation, ACLs and such bring global but perhaps auth and others being per action.
Wondering if a middleware addition could be the place to declare that it's global or not. Rather than a global config for all middleware. Or maybe both but the former overrides the latter
Evan Tahler @evantahler Apr 06 2015 01:27
Each middleware had a global or not flag. You choose per middleware. Also, each action can opt into the rest of the non-global middleware. I guess that isn't clear
Neil Craig @neilstuartcraig Apr 06 2015 03:28
Ah cool. That's great then. I misunderstood. Sounds perfect.
Neil Craig @neilstuartcraig Apr 06 2015 04:10
Just one q. Are the action names to apply the middleware to glob-able? I'll take a proper look but I'm hoping to replace my dynamic pre/post processor plugin
Evan Tahler @evantahler Apr 06 2015 08:35
Not now, but they can be! Add a comment to the PR saying you want regex!
Neil Craig @neilstuartcraig Apr 06 2015 12:40
Cool, i’ll do it! Thanks...
Amine Mouafik @kytwb Apr 08 2015 00:11
anybody have an up-to-date ah-nodemailer-plugin at hand? the one listed on the website looks like way too out of date and unmaintained
Greg Coonrod @gcoonrod Apr 08 2015 07:58
@evantahler Does api.cache.lock create a lock that prevents multiple workers on the same AH server from accessing the Redis key at the same time? Or does it only prevent workers on separate servers from accessing the same Redis key at the same time?
Greg Coonrod @gcoonrod Apr 09 2015 11:46
any best practices with logging when running ActionHero as a cluster using startCluster?
Evan Tahler @evantahler Apr 09 2015 12:40
cache.lock locks the item for everyone until it times out or locks it. So subsequent calls, from even the same process, are blocked.
no best practices... everything should already be logged to the files
Greg Coonrod @gcoonrod Apr 09 2015 12:41
welp, then i'm very clearly misusing locks
i'm not using file logging. I'm capturing the console output and appending it to a file. but that no longer functions when i switch to a cluster
Neil Craig @neilstuartcraig Apr 09 2015 12:42
is there a reason you wouldn’t want to use api.log()?
it works well for me in what i have done so far with AH
Greg Coonrod @gcoonrod Apr 09 2015 12:52
i am using api.log
i'm just not telling winston to write to a file
i only have winston log to the console
Neil Craig @neilstuartcraig Apr 09 2015 12:57
ah i see. sorry, i misunderstood.
ah Evan says, amending the logger config to write to a file sounds like a good plan
Greg Coonrod @gcoonrod Apr 09 2015 12:59
yes, i had hoped to avoid that, as the file format that winston uses is json, which isn't as easy to parse in the linux console.
we're trying to move our developers to running AH in a cluster even during development so we can vet things before pushing to production
Neil Craig @neilstuartcraig Apr 09 2015 13:01
if you check the docs: https://github.com/winstonjs/winston
json formatting is optional
https://github.com/winstonjs/winston#file-transport
so you can probably get a simpler format by passing json:false
Greg Coonrod @gcoonrod Apr 09 2015 13:02
ah, thanks!
Neil Craig @neilstuartcraig Apr 09 2015 13:02
no worries :-)
Greg Coonrod @gcoonrod Apr 09 2015 13:15
hmm, so my workers are respecting the json: false flag. But cluster.log is still in json format. Even after a full cluster restart.
Neil Craig @neilstuartcraig Apr 09 2015 13:19
That’s odd. Did you (re)move the existing log file?
Just in case the logger honours existing file format - probably unlikely
Evan Tahler @evantahler Apr 09 2015 13:59
The cluster-master logger is kind of lame. We need to start logging before we actually find the log file (it's a catch 22), so we have a custom logger in the binary https://github.com/evantahler/actionhero/blob/master/bin/actionhero#L27-L47
if you want, send in a PR to move the logger until after we find the binary.paths.projectRoot so we can source the logger config
that would be awesome
Greg Coonrod @gcoonrod Apr 09 2015 14:41
@evantahler Is that the cluster.log creation point? I'm looking at startCluster.js and it has the winston file logger instantiation.
Evan Tahler @evantahler Apr 09 2015 16:08
Huh. We should source the one from the binary. That's silly
Richard Hall @richardardrichard Apr 10 2015 11:10
Hello! We are using actionhero for a few of our projects, and its awesome! I seem to be having an issue with "periodic" tasks though (maybe missing something obvious!?). We are using actionhero 9.1 in a project, and it seems that if we schedule a "periodic" task, the workers won't pick up any of the "normal" jobs in the queue?
If I stop the server, make the periodic task into a normal task, and restart the server then the other normal jobs get picked up immediately.
Actually I guess I fixed this already... Having separate workers for default, and periodic jobs seems to have fixed the issue
Evan Tahler @evantahler Apr 10 2015 14:39
Yay
Evan Tahler @evantahler Apr 11 2015 08:31
Check the queues you are working.
Evan Tahler @evantahler Apr 12 2015 08:08
@/all I think version 11 is about ready to go out evantahler/actionhero#623 Let me know any last minute thoughts! This release DOES NOT include generators, so you can still use node v10
yes, this version breaks ALL existing actions
Neil Craig @neilstuartcraig Apr 12 2015 08:22
It also breaks middleware right?
I'll need to update a number of plugins so happy to write a little guide to updating if it's useful?
ive got a minor new feature to propose soon but if accepted, that can be 11.x
Evan Tahler @evantahler Apr 12 2015 10:11
Yep, middleware broken too
a guide would be helpful, yes!
if you get it in tonight, I guess?
probably best to wait untill 11
er
12
Neil Craig @neilstuartcraig Apr 12 2015 13:26
Ok cool. I'll try to write some notes as I'm updating.
I think my change will be a minor as it is literally just a small new feature on the actionhero "binary". I'll sort it and send a PR so you can see what I'm thinking. Cheers.
Neil Craig @neilstuartcraig Apr 13 2015 08:45
Hi guys - maybe @evantahler is best placed to answer this - not sure…is there a prettifier anywhere in AH curently? I don’t see one…
The reason i ask is that when editing the config files, they get flattened and become difficult to work with manually.
I’m hesitant to be asking to add another dep so if there’s something already available then i’d prefer to use that
Evan Tahler @evantahler Apr 13 2015 12:15
Why do they get flattened? That's odd
Neil Craig @neilstuartcraig Apr 13 2015 12:41
IT’s because I want to read the JSON then modify it and write the JSON out - not ding string replaces
i’ve just been thinking - this is bigger than what i’d been planning - what about some generic method for add/edit/delete on config files?
maybe not enough demand…not sure, just spitballing it
Evan Tahler @evantahler Apr 14 2015 00:05
I don't really understand what you are working on configs should be immutable?
Neil Craig @neilstuartcraig Apr 14 2015 01:24
Sorry, it's hard to explain here. I'm not too far off done with my little feature update. I'll write up my issue/thoughts after that.
Neil Craig @neilstuartcraig Apr 14 2015 14:19
Hi again guys. I have just pushed my draft for an addPlugins method for the actionhero binary
https://github.com/neilstuartcraig/actionhero/blob/master/bin/methods/addPlugins.js
(it’s a fork from the v10 master)
I have not created tests yet as it’s just a draft
This functionality is pretty essential for me to be able to add plugins during an installer phase for my project (which is based on actionhero plus a load of plugins)
Writing the updated config/plugins.js file is a bit clunky/messy as it’s not “just” a JSON file
I must assume that the config/plugins.js file may have been modified - hence the approach.
if anyone has better ideas or any Qs then please let me know
I’d like to get this change in there somehow but obviously that’s not my decision - what do you guys think?
my further ideas:
Allow adding plugins to one/several defined environments (dev/stage/test/live etc.)
Refactor the generate amend I made for v10 to use the new addPlugins method to keep it DRYer
Possibly consider some form of generic method to programmatically amend config files
ha
sorry, gitter made all my items #1
:-)
Evan Tahler @evantahler Apr 15 2015 00:58
what's an invocation look like?
please don't include JSLInt/JSHint code
(not all people use it)
Neil Craig @neilstuartcraig Apr 15 2015 01:04
No worries, i can remove the jshint
So to invoke, you’d use it like generate, e.g.:
./node_modules/actionhero/bin/actionhero addPlugins plugins=plugin1,plugin2,...
So this could be done at any stage, provided generate has been run (i.e. there is a config file)
I may need to add some checks to ensure that generate has been run though
This was just a sketch
If you don’t feel it fits in core then i’ll make a plugin from it and use it that way in my projects
Evan Tahler @evantahler Apr 15 2015 02:26
yeah, I don't really think that it clasifies as a 'generator', since it really is just adding things to a config file. The generators are meant to "create" files.
but... what does everyone else think?!
Neil Craig @neilstuartcraig Apr 15 2015 03:17
Sorry to jump in but just to say, addPlugins doesn't hang off generate, it's standalone
my thinking is also that plugin installers could use it to add themselves to the config file.
Neil Craig @neilstuartcraig Apr 15 2015 07:47
@/all any opinions on this either way? Keen to get a direction one way or the other. :-)
Andrew Vaughan @andrewvaughan Apr 15 2015 17:37
Hey @all - I'm running into this TypeError (https://gist.github.com/andrewvaughan/ed255aa5d58b4d91f3a8) when invoking this action (https://github.com/gizmoboard/gizmoboard/blob/config-cleanup/src/server/actions/admin.js#L29) - any idea what I'm doing wrong? Seems to have an empty api object within the actionhero "stop" command
Evan Tahler @evantahler Apr 16 2015 04:09
Yeah, there's a scoping issue. This works api.commands.stop.call(api._self). That said, depending on how you are running the server, the "container" may not actually stop. For example, calling stop in that way will not exit the start binary wrapper as we aren't polling or checking state. You'll probably need a process.exit() in there afeter the stop callback.
Andrew Vaughan @andrewvaughan Apr 16 2015 07:33
Yeah I threw that in - thanks!
Tobias Braune @tbraune89 Apr 17 2015 03:16
Hey guys, i am looking for a good authentification component. Are there OAuth packages you would prefer to integrate in ActionheroJS? Basically it should be fast & nice, any recommendations?
Neil Craig @neilstuartcraig Apr 17 2015 03:18
Hey @tbraune89. I started a passport plugin a short while back which seems to work: https://github.com/neilstuartcraig/ah-passport-plugin
That might be worth a quick try. You can use any passport strategies with it: http://passportjs.org/
It is only a starter but it seemed to work OK with the github strategy at least
There are a number of oAuth strategies and you should be able to combine as many as you want
Let me know how you get on if you do try it, i am interested to improve it but I don’t have the time to test much right now
Tobias Braune @tbraune89 Apr 17 2015 03:21
Yeah great thanks, i'll give it a try @neilstuartcraig !
Neil Craig @neilstuartcraig Apr 17 2015 03:24
cool! best of luck - and please don’t hate me if it’s terrible
Tobias Braune @tbraune89 Apr 17 2015 03:54
Haha, dont mind PassportJS uses multiple different OAuth-Clients, right? I forgot to write that i need to secure my API, means i am looking for a OAuth-Server...
Neil Craig @neilstuartcraig Apr 17 2015 04:04
So you want to be an oAuth provider?
Tobias Braune @tbraune89 Apr 17 2015 04:07
Yeah right! And if i am right, at least all packages are sitting on express... Does it matter?
For example this looks okay: https://github.com/jaredhanson/oauth2orize
Neil Craig @neilstuartcraig Apr 17 2015 04:09
well, i guess if you used that, you’d need to run it as a separate process to actionhero - unless you do some integration
passport itself is designed to run under express (or at least, that’s supported) so i had to do some work to allow it to get the info it needs from actionhero
luckily, people smarter than me had pretty much figured this out so it was quite easy for me to build the passport plugin
i’m not quite sure why you need to run an oauth server though
what would you need to do that for?
Tobias Braune @tbraune89 Apr 17 2015 04:14
we're running some smartphone/client-apps, they're using actionhero endpoint to retrieve database-data. in future, this should be only possible with one secure authentification
Neil Craig @neilstuartcraig Apr 17 2015 04:15
i see, so you don’t want people/apps to auth against e.g. twitter
you could use a different auth strategy
unless you have a hard requirement that it’s oauth
if you used a local strategy then you could auth against a local DB on the actionhero server
that way you don’t have to create an oauth server
or...
you could try my other auth plugin: https://github.com/neilstuartcraig/TDPAHAuthPlugin
that is a local auth system which runs off mongodb
it has an accompanying ACL module too
https://github.com/neilstuartcraig/TDPAHACLPlugin
the two work quite nicely together
i am sure there are others too
Tobias Braune @tbraune89 Apr 17 2015 04:19
okay nice to know, is it easy to change mongodb to postgresql?
Neil Craig @neilstuartcraig Apr 17 2015 04:19
but it sounds like a local auth strategy for passport or a local auth plugin would be good - unless you must use oauth
not on mine…sorry
i hate ORMs
Tobias Braune @tbraune89 Apr 17 2015 04:20
:D haha, ORMs are fine!
Neil Craig @neilstuartcraig Apr 17 2015 04:20
my code is very coupled to mongoskin
you could always fork and change or see if someone else has an auth plugin which can use ORM/postgres
Tobias Braune @tbraune89 Apr 17 2015 04:21
yeah, i dont know if a local strategy is okay
Neil Craig @neilstuartcraig Apr 17 2015 04:22
sounds like it’d be more sensible but then i only know 0.000001% of your requirements :-)
Tobias Braune @tbraune89 Apr 17 2015 04:26
you're right, it will be very sensible. we're trying to aim that result like facebooks graph, it is a very large project...
Neil Craig @neilstuartcraig Apr 17 2015 04:27
so if there will be a lot of requests, you might want to separate the server roles i guess…have actionhero query another server for auth
you could do that over a socket connection perhaps - using an ah client
would keep it fast and allow you to scale the two independently
anywya...
we’re OT now :-)
Tobias Braune @tbraune89 Apr 17 2015 04:29
great idea, thanks
Neil Craig @neilstuartcraig Apr 17 2015 04:31
shout if i can be any help with plugins etc. though
i’m interested to hear success/issues/ideas
i will update them to ah v11 when that comes along too
Tobias Braune @tbraune89 Apr 17 2015 04:33
yeah dude, thank you! maybe i'll come back to you, if we're more into the requirements...
Neil Craig @neilstuartcraig Apr 17 2015 04:35
cool, sounds good. hope it goes well
Evan Tahler @evantahler Apr 17 2015 07:14
I disagree with @neilstuartcraig, @tbraune89. PasportJS and https://github.com/jaredhanson/oauth2orize (an oauth server) are made for express, but can be made to work easily with anything which has the normal node HTTP req and res objects (last time I tried anyway).
That said, if you just want to secure your api @tbraune89 all of this is probably overkill when a simple session cookie and auth will do
no need to go binding to other services or anything like that
Tobias Braune @tbraune89 Apr 17 2015 08:42
@evantahler thanks for pointing that out, i'm really new here... i dont know how to decide, that OAuth features are really pretty, but we just need simple acl and auth integration. I'll consider with my colleague the next days. Do you prefer any local auth system?
Evan Tahler @evantahler Apr 17 2015 08:43
I mean... I assume you have a users table in your database? With salts and password hashes?
This is an example for a very old version of actionhero, but you can set that up pretty simply http://blog.evantahler.com/blog/authentication-with-actionHero.html
Tobias Braune @tbraune89 Apr 17 2015 08:44
Yeah thats the problem, we got users, but for now they're connection trough 3rd-party API's like Twitter or Facebook...
In this case they are not really registered with password & salt... And i would like to restrict specific actions bound to the active user only.
Thanks for your thoughts
Evan Tahler @evantahler Apr 17 2015 10:22
Sure, but then you have a berrer token which should match the client
Same deal
Evan Tahler @evantahler Apr 19 2015 07:45
@andrewvaughan evantahler/actionhero#637 should solve your api.commands... troubles
Evan Tahler @evantahler Apr 19 2015 08:01
RELEASE
https://github.com/evantahler/actionhero/releases/tag/v10.1.2
v10.1.2
@evantahler evantahler released this 5 minutes ago
Web Client Library Updates
Modify webAction() so that HTTP clients (or not-yet-connected websocket clients) can use complex object payload (switching from GET to POST).
by @samuelbrian via #619
Misc
fixed ability to stop/start/restart the server from within in action (ie: api.commands.stop())
by @evantahler via #637
Upgrade dependent packages to latest versions.
fakeredis
formidable
grunt
node-uuid
Various test suite fiexes
Downloads
Evan Tahler @evantahler Apr 20 2015 05:38
@/all Version 11.0.0 is released!
note: this version did not include anything about generators and --harmony requirements... that was moved to a future release
Evan Tahler @evantahler Apr 20 2015 06:34
Here's what it looks like to update a project to v11 evantahler/actionhero-tutorial#13
Chad Robinson @crrobinson14 Apr 20 2015 06:39
@evantahler Anything specific I should know about v11 w/r/t the mdidleware changes for v12? I've finally cleared my plate and was planning to cover that this week.
Evan Tahler @evantahler Apr 20 2015 06:41
@crrobinson14 pretty sure I did that for you :D evantahler/actionhero#625
Chad Robinson @crrobinson14 Apr 20 2015 06:42
Saw that, thanks. Was just making sure I didn't miss anything else from this convo. I've been completely out of touch - 18-hr days on this other thing.
Guess there's nothing for me to do. :)
I'll convert to the new setup and let you know how it goes.
dunse @dunse Apr 20 2015 07:17
q: in a test case, how can I acquire a connection.fingerprint that will be used when opening a websocket connection (using clientA.connect() as in the actionhero tests)?
dunse @dunse Apr 20 2015 07:32
btw "the connection middleware is still async (it has no callback; nor does it return). It will not block the connection being created.".. No callback, so it's sync.. Also, it does block connection being created..
or it at least blocks it from finishing..
Evan Tahler @evantahler Apr 20 2015 08:24
@dunse I'm pretty sure that's not true (unless you are doing something CPU intensive in the connection middleware). The event emitters will fire as soon as you yeild to the first callback in that middleware
and @dunse connection.fingerprint is only available after connection (the server sets it). http://i.imgur.com/vp7N0zo.png
dunse @dunse Apr 20 2015 08:29
I was doing something CPU intensive :) I'll do something less intense to double check
Yes, connection.fingerprint sets after a request been done to 'web' server.. but how can we simulate this in an integration test? (test/servers/websocket.js, when clientA.connect runs, we don't have a session cookie)
I tried this:
request.post(url + '/' + urlPathForActions + '/1/login', { form: { 'username': 'allowed', 'password': 'pass' } }, function (err, response, body) {
clientB.connect(function(err, data) {
clientB.roomAdd('defaultRoom', function (data) {
but it doesn't works since I can't share the "cookieJar" with "clientB" (if that make sense)
Evan Tahler @evantahler Apr 20 2015 10:28
As far as I know, you can't do that with out a real browser. Sadly, I can't even test it in core. That test has been sadly pending for months.
Chad Robinson @crrobinson14 Apr 20 2015 12:28
It depends how you want to run your tests. We just used Curl from the command line. All you need is the cookie-jar setting (-c) and the fingerprint cookie from the first request will be persisted for the second. It's also very easy to do when using Protractor/Selenium to write E2E in-browser tests.
As hackish as it sounds, you can use execSync or similar to run these as external scripts frmo within Mocha (or whatever testing framework you use).
I mean, if you're philosophically opposed to doing it this way, it's obviously not a perfect solution. But if what you WANT is to have a TEST, it works great.
jamesmr89 @jamesmr89 Apr 20 2015 12:40
I'm having a hard time figuring out the apiVersion scheme
I can make a get request to /api/AppVersion?apiVersion=1
and i get a response from the server that includes: "serverInformation": {
"serverName": "my Server",
"apiVersion": "1.0",
"requestDuration": 1,
"currentTime": 1429558696613
},
but making a request to /api/AppVersion?apiVersion=1.0 comes back with:
"error": "Error: unknown action or invalid apiVersion",
but the apiVersion in the serverInformation and the requestInformation both match.
jamesmr89 @jamesmr89 Apr 20 2015 13:00
ok, i think i've resolved this, the apiVersion must match the action version, once I did this all is working as expected.
Evan Tahler @evantahler Apr 20 2015 13:07
@crrobinson14 would you mind trying to get that working in the core test suite? The fingerprint test here could use some love https://github.com/evantahler/actionhero/blob/master/test/servers/websocket.js
@jamesmr89 cool
Chad Robinson @crrobinson14 Apr 20 2015 13:17
@evantahler Yes... but something needs to provide the cookie support to execute a request pair that persists the fingerprint. What would you be comfortable tying to - whatever it is will become a dependency. cURL feels like the wrong answer there.
What about npm request?
That supports cookie-jar persistence through tough-cookie, which allows you to configure In-Memory persistence. No artifacts to clean jup
dunse @dunse Apr 20 2015 22:27
@evantahler finally got it working.. the trick is to override the http/https.request and inject your cookies there..
@crrobinson14 sounds like it will become very messy calling external programs when testing all different branches.. I'm miles away from any web ui, so no selenium as of yet :)
Evan Tahler @evantahler Apr 21 2015 03:27
@dunse, this is awesome!
dunse @dunse Apr 21 2015 03:28
That's in a very simplified way how 'nock' works
Chad Robinson @crrobinson14 Apr 21 2015 06:13
Yeah, Selenium is very heavy - I only brought it up as one thing that definitely works. The same goes for cURL. I still think you can do a simple test using a common NodeJS library, like request. You can also hard-wire this if you don't mind picking through the response object to find the appropriate fingerprint cookie and carrying it through to the next request. Is that what you did?
dunse @dunse Apr 21 2015 06:45
You can see the full change here: https://github.com/evantahler/actionhero/pull/640/files#r28766108
It does pull out the cookie out of the response and then pass it to the subsequent request.
Nick Collins @ndcollins Apr 21 2015 22:38
I have a client that is using Recurly for their subscription management. One of their requirements is that they want to be able to request the PDF of the accounts invoices/receipts, which the Recurly API provides a method for. The problem I am running into is that somewhere between requesting the data from their API and returning it through the connection.response the PDF data is getting corrupted such that it cannot be read by Acrobat or any other PDF reader. Any suggestions?
salles @sallespro Apr 21 2015 22:43
is it chunked ? have you checked the response headers ?
Nick Collins @ndcollins Apr 21 2015 22:45
it is chunked
transfer-encoding is chunked, content-transfer-encoding is binary
using the request library, it is returning a Buffer
Nick Collins @ndcollins Apr 21 2015 22:54
The Buffer contains all the bytes of the actual PDF file. Is there some way I should transform the Buffer before adding it to the response?
Evan Tahler @evantahler Apr 22 2015 00:23
Can you share some code?
dunse @dunse Apr 22 2015 06:17
@evantahler for the chatMiddleware.. the say: handler is called once for every connection in a specific room. Was that intended? I would have thought it was called only once regardless of the number of current connections..
Nick Collins @ndcollins Apr 22 2015 06:19
connection.rawConnection.responseHeaders.push(['Content-Type', "application/pdf; charset=utf-8"]);
connection.rawConnection.responseHeaders.push(['Content-Disposition', 'attachment; filename="' + invoiceNumber + '.pdf"']);
var authorization = "Basic " + (new Buffer ( config.API_KEY )).toString ( 'base64' );
var options = {
url: "https://" + config.SUBDOMAIN + ".recurly.com/v2/invoices/" + invoiceNumber,
headers: {
'Authorization': authorization,
'Accept': 'application/pdf',
'Content-Length': 0
},
encoding: null
};
function callback(error, response, body) {
if ( error ) {
connection.error = error;
}
if (!error && response.statusCode == 200) {
connection.response = body;
}
next ( connection, true );
}
request(options, callback);
Evan Tahler @evantahler Apr 22 2015 07:48
@dunse yeah, the middleware runs for each client in the room. The reason for that is to facilitate things like blocking admin messages, or appending useful metadata like (message from your team), etc
@ndcollins {chunked: false, data: []} checkout the readme for request @ https://github.com/request/request
there are some special options you need for chunked data
dunse @dunse Apr 22 2015 08:03
@evantahler Maybe there should be a pre and a post for say? The example in the doco specifies "api.log(messagePayload);", with 100 users in a room, this would be printed 100 times in the log..
Evan Tahler @evantahler Apr 22 2015 08:13
yay! hooked up heroku deploy hooks for demo.actionherojs.com to this gitter room!
@dunse pre, as in "before, happens once" and then post, as in "for all connections"?
if so, sure! send in a PR!
maybe sayAll vs sayEach
something like that
Evan Tahler @evantahler Apr 22 2015 08:29
If anyone uses actionhero with a coffeescript project, please add some suggestions here evantahler/actionhero#638
Nick Collins @ndcollins Apr 22 2015 08:36
@evantahler isn't that for sending chunked data to the server from a multi-part form? In my case I'm not sending any data to the service, the service is sending chunked data back to me
Evan Tahler @evantahler Apr 22 2015 11:07
Whoops. Then.. I don't know :(
Nick Collins @ndcollins Apr 22 2015 11:25
I have all the bytes of the file in a Buffer that the service returned, if I use POSTman to call the service directly, I get a valid PDF, if I use request or superagent to make the same call, and return it as the connection.response, it is corrupted somehow
would Actionhero be doing anything with the response that could be altering the buffered data?
Evan Tahler @evantahler Apr 22 2015 14:57
We would be stringifying it maybe? You probably should return that file manually with the right headers. And don't ToRender that action. Remind me tomorrow and I'll take a look
Devin Despain @dangerdespain Apr 23 2015 03:32
hey @evantahler, I'm running into some weird cases where tasks run and I'm able to make http requests before the initializer start functions are complete. I was hoping to prevent this by using api.initialized or api.running but they're both set to true before the start function callbacks return
is it possible that this was broken during the 9.x -< 10.0 initializer refactor or is this the expected behavior?
if my server is down for any period of time and I have tasks to run on startup, a ton of sequelize association errors are barfed out since my db initializer hasn't finished loading by the time the tasks start running
Evan Tahler @evantahler Apr 23 2015 05:22
You can change the load priority! Make sequelize load before tasks.
(And the init priority)
Devin Despain @dangerdespain Apr 23 2015 06:38
Ahh, thanks! No stupid questions, just inquisitive idiots right? (:
Evan Tahler @evantahler Apr 23 2015 07:43
also, you probably want to connect to your DB in the init step, so it's ready for tasks in the start step. All 'initializes' happen before all 'starts'
James Crosswell @jamescrosswell Apr 23 2015 13:56
So, newbie question... where does the term "initializers" come from. I was reading through the tutorial scratching my head for a bit - wondering what the heck an "initializer" was. Then when it finally got to the actions bit I see initializers (at least as they are used in the tutorial) are basically just used as a kind of Data Layer.
omichowdhury @omichowdhury Apr 23 2015 14:14
@jamescrosswell Initializers are run when an instance starts up, they set up the environment for actions and tasks to run. Data layer stuff like you mentioned, but also adding pre and post processors, adding shared code you want on the api object etc
Evan Tahler @evantahler Apr 24 2015 02:48
Good answer! Initializers "set up the server" rather than deal with any client requests. They might load up middleware, connect to databases, etc
Chad Robinson @crrobinson14 Apr 24 2015 06:31
It might also be worth mentioning that ActionHero uses its own initializer support layer to provide the rest of its internal services, like task and action processing, serving static files, etc. That's one of the things we liked about it - frameworks that use themselves to EXTEND themselves tend to be much more modular and flexible in the long run (IMO). Drupal does the same thing and it's one of the reasons it's so popular with developers.
Siddique Ahmad @SiddiqueAhmad Apr 24 2015 10:11
how can i call action 2 in action 1
Evan Tahler @evantahler Apr 24 2015 11:12
I agree
You really can't call action 1 from 2 efficiently. Anything common move into a shared method in an initializer.
Siddique Ahmad @SiddiqueAhmad Apr 24 2015 12:18
Thanks got it
James Crosswell @jamescrosswell Apr 24 2015 13:23
OK thanks all
Sebastien Stettler @billybonks Apr 25 2015 03:33
is there a front end that i can use to view running tasks
Evan Tahler @evantahler Apr 25 2015 03:58
There's the status API route. Tasks has some stays stuff
Sebastien Stettler @billybonks Apr 25 2015 05:02
cool
Sebastien Stettler @billybonks Apr 25 2015 05:51
api.tasks.enqueue("sendWelcomeEmail", {to: 'evan@evantahler.com'}, 'default', function(err, toRun){
// enqueued!
});
the callback is called after the job is enqued ?
is it a bad pattern to want to do something after a job completes ?
Evan Tahler @evantahler Apr 25 2015 06:10
You can't be sure the job will run on the same server as the enquing
The enquing callback is just enquing. Not running.
Sebastien Stettler @billybonks Apr 25 2015 07:46
ok
do you have any advice about handling unexpected errors in promises the workers to hang, because the error doesn't bubble?
Sebastien Stettler @billybonks Apr 25 2015 08:33
never mind found a solution
:+1:
can jobs retry if they fail ?
Evan Tahler @evantahler Apr 25 2015 09:35
They will be put in the failed queue in redis. You can do whatever you want from there. You'll maintain the original queue, Paramus, and the err stack.
Evan Tahler @evantahler Apr 26 2015 04:36
actually,
I'll add some commands to https://github.com/taskrabbit/node-resque to look at the failed jobs and retry them
Evan Tahler @evantahler Apr 26 2015 06:23
And here they are taskrabbit/node-resque#74
Evan Tahler @evantahler Apr 26 2015 06:41
ok! and now we can work with the failed queue within actionhero https://github.com/evantahler/actionhero/releases/tag/v11.1.0
Sebastien Stettler @billybonks Apr 26 2015 07:02
nice :+1:
Tobias Braune @tbraune89 Apr 26 2015 11:23
evan is going crazy...
Evan Tahler @evantahler Apr 26 2015 13:21
Oh?
Evan Tahler @evantahler Apr 27 2015 02:47
Minor release update v11.2.0: Now messages "you say" will be returned to you in chat. It's up the client to filter them out if he wants, etc
Evan Tahler @evantahler Apr 27 2015 03:42
Here is an example plugin on how to save chat messages https://github.com/evantahler/ah-chatlog-plugin
Greg Coonrod @gcoonrod Apr 29 2015 10:48
How does one check the status of resque in AH v10? I'm seeing some odd behavior where task processing seems to halt until AH is restarted.
Devin Despain @dangerdespain Apr 29 2015 12:23
I've had the same issue as well.. every so often a redisFlush command is the only thing that'll kickstart tasking
Greg Coonrod @gcoonrod Apr 29 2015 12:58
If you flush Redis won't that remove all the pending tasks?
Devin Despain @dangerdespain Apr 29 2015 12:59
Yup.. we're still in development mode so it's keeping us moving but definitely not a production solution
Greg Coonrod @gcoonrod Apr 29 2015 12:59
Yeah, that's a no go for me.
Devin Despain @dangerdespain Apr 29 2015 13:00
We really just started tackling this today as well, if I discover anything I'll make sure to share the juicy details
Greg Coonrod @gcoonrod Apr 29 2015 13:00
Thanks!
Evan Tahler @evantahler Apr 30 2015 00:03
Could also mean that your workers are stuck (never called back).
There are some task status APIs (check the default status action)
You can also try our redis-commander for a good redis GUI
Devin Despain @dangerdespain May 02 2015 01:44
my latest strategy - wrapping any task logic inside a promise (<3 Bluebird) with a .catch() method to handle/log pesky exceptions and a .finally() to fire the callback. I'm also considering implementing a timeout on the Promise chain as a last defense against hung tasks.
Evan Tahler @evantahler May 02 2015 07:09
Nice! Let us know how it goes
Tobias Braune @tbraune89 May 04 2015 09:45
Hey, i am trying to use this: https://github.com/thomseddon/node-oauth2-server in actionhero. My problem is: some components are based on express request and response objects. Is there a way to port or adapt this 2 express objects to actionhero? Let me know if you've any ideas.
Evan Tahler @evantahler May 04 2015 10:50
@neilstuartcraig has been working with oauth and may have some pointers.
Neil Craig @neilstuartcraig May 04 2015 10:52
Hi @tbraune89. Yep, @evantahler is right, I took the work of others and made a plugin for passport which sounds similar.
have a look at the initialiser: https://github.com/neilstuartcraig/ah-passport-plugin/blob/master/initializers/ah-passport-plugin-initialiser.js
There are a couple of references in the comments in that file if you need them.
Let me know if you have any questions after that and I'll try to help
Tobias Braune @tbraune89 May 04 2015 10:53
yeah nice thank you, ill have a look!
Neil Craig @neilstuartcraig May 04 2015 10:54
No worries. It was relatively simple though as I say, I really just took the work of others in most aspects of that plugin.
Devin Despain @dangerdespain May 04 2015 22:18
Has anyone been successful with CPU/memory profiling with AH? I've spent quite a few hours banging my head against the different profiling tools and can't seem to generate/view any useful data. Running node v0.10.33 and AH 10.1.2
Any pointers would be incredibly appreciated
Evan Tahler @evantahler May 05 2015 02:34
version 11.2.1 up! https://github.com/evantahler/actionhero/releases/tag/v11.2.1
@dangerdespain node is... hard do debug. What are you trying to sort out? Event loop blocking is the best way to get to the bottom of CPU bottlenecks, and object spaces dumps are the best way to sort out memory leaks (in my experince)
Devin Despain @dangerdespain May 05 2015 05:08
Well, we're experiencing silent (from the AH log standpoint) crashes under load and are struggling to figure out why
I've managed to squeeze out a few heap dumps from fresh and longer running instances and the non-load heap size seems to be pretty stable so I (perhaps incorrectly) assume we're not looking at a memory leak issue
We've got plenty of swap available on the box as well
Neil Craig @neilstuartcraig May 05 2015 05:12
@dangerdespain - did you try anything like strace, dtrace etc yet? I always meant to go for it after reading this http://blog.nodejs.org/2012/04/25/profiling-node-js/
i believe iojs has a load more dtrace hooks than node used to
i have a colleague or two i can probably hassle into helping a little with an intro so shout if you are still stuck
Devin Despain @dangerdespain May 05 2015 05:13
node 0.10 seems especially light on the debugging support compared to 0.12 and iojs
I'll get rolling on some sweet flame graphs! Thanks for the link
A proper visualization for a coder->architect style trial by fire, eh?
Neil Craig @neilstuartcraig May 05 2015 05:16
yeah, definitely - 0.12+ and iojs are getting much better debugging support. from what i hear, you’ll be much better off with iojs as the more modern V8 has way more hooks
the chrome/V8 guys have been much more engaged in iojs as I’m sure you’ll know :-)
Devin Despain @dangerdespain May 05 2015 05:19
I'll see if I can't sneak it onto our servers while the boss is in Vegas at Collision Conference ;)
Alright.. time for a deep dive
Thanks @neilstuartcraig and @evantahler !!
Neil Craig @neilstuartcraig May 05 2015 05:28
No worries, best of luck. It’d be great if you are able to keep some notes to share or even better, maybe a blog post?
Devin Despain @dangerdespain May 05 2015 05:54
The blog will happen for sure if we can ever get this damned beta product out the door! :D
Neil Craig @neilstuartcraig May 05 2015 05:56
Ha ha, great. Hope it’s not too much (more) pain :-)
Evan Tahler @evantahler May 05 2015 12:19
Huzzah for blog posts! Related; if you look in the public folder on github, you'll find some high res actionhero assets for just this purpose.
fas3r @fas3r May 06 2015 18:49
Hello
omichowdhury @omichowdhury May 06 2015 18:53
@fas3r Hi
Evan Tahler @evantahler May 07 2015 04:44
what's up?
Sebastien Stettler @billybonks May 09 2015 01:33
do we have like a actionhero plugin registry ?
Evan Tahler @evantahler May 09 2015 02:43
Just a list on the website. And it is out of date
Sebastien Stettler @billybonks May 09 2015 02:56
kk
Sebastien Stettler @billybonks May 09 2015 03:14
hmm, actionhero.start is null when running the example test
"actionhero": "10.1.0",
Neil Craig @neilstuartcraig May 09 2015 03:47
We have the recommended naming convention of ah-<plugin-name>-plugin so I was thinking we could use the npm Ali to list packages which match that convention. I think that's doable isn't it?
Sebastien Stettler @billybonks May 09 2015 03:47
was thinking the same
Neil Craig @neilstuartcraig May 09 2015 03:48
Great minds :-)
Sebastien Stettler @billybonks May 09 2015 03:48
:), what do you think of my previously mentioned error
about tests
Neil Craig @neilstuartcraig May 09 2015 03:53
I don't know anything much about the tests, sorry. I'm away from my computer at the moment too.
Sebastien Stettler @billybonks May 09 2015 03:58
np
Evan Tahler @evantahler May 10 2015 12:01
What example test?
Sebastien Stettler @billybonks May 10 2015 19:59
process.env.NODE_ENV = 'test';
var should = require('should');
var actionheroPrototype = require('actionhero').actionheroPrototype;
var actionhero = new actionheroPrototype();
var api;
describe('actionhero Tests', function(){
before(function(done){
console.log(actionheroPrototype);
actionhero.start(function(err, a){
api = a;
done();
})
});
after(function(done){
actionhero.stop(function(err){
done();
});
})
it('should have booted into the test env', function(){
process.env.NODE_ENV.should.equal('test');
api.env.should.equal('test');
should.exist(api.id);
});
});
Evan Tahler @evantahler May 11 2015 02:16
@kytwb I see you started a hipchat + actionhero plugin a while back. I made one here https://github.com/evantahler/ah-hipchat-server-plugin which treats incomming hipchat commands as actions (/myAction some data)
@billybonks that example test works fine in a fresh actionhero install (v11)
can you ensure that your server actually boots in the test env? NODE_ENV=test npm start
Sebastien Stettler @billybonks May 12 2015 04:24
not sure what change i made but its working now
Evan Tahler @evantahler May 12 2015 05:03
Lol... Hooray!
Greg Coonrod @gcoonrod May 12 2015 18:37
Anyone able to share some wisdom on debugging stuck workers?
Evan Tahler @evantahler May 13 2015 05:44
it's almost always an un-filled callback. add tons of logging, every callback.
sometimes connections to DBs go away, etc
Greg Coonrod @gcoonrod May 13 2015 12:27
Pro-tip: Make sure your tasks always call next()!
Neil Craig @neilstuartcraig May 13 2015 13:00
Ha ha. We've all done that one. I spent ages pulling an initialiser apart several times, only to discover I'd done the same :-)
Evan Tahler @evantahler May 13 2015 14:30
I wonder if js has a static analyzer for checking if a callback is possible. That would be useful
Greg Coonrod @gcoonrod May 13 2015 14:31
Yes, though the task i'm working on are made all the more complex by the use of Q promises.
My team was discussing adding in some sort of watchdog process to AH that could use the queue.cleanOldWorker() method or some other similar logic.
Evan Tahler @evantahler May 14 2015 02:56
Meta. Use a task to manage tasks.
Just make sure that first task actually has a callback :D
Sebastien Stettler @billybonks May 14 2015 09:19
so my server takes 4s to start up is that normal ? i only realised this because i was gettting
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
Evan Tahler @evantahler May 14 2015 11:43
Depending on what services you connect to it might be. You can always change the timeouts in tests
Sebastien Stettler @billybonks May 14 2015 20:20
ye i did change the time out
Evan Tahler @evantahler May 17 2015 02:07
New version released
https://github.com/evantahler/actionhero/releases/tag/v11.2.2
donnyhardyanto @donnyhardyanto May 18 2015 21:29
Hi Mr. Evan. I need to use ActionHero web socket with Android. Please can you point me how to do it? I tried using Android Primus library and it not working.
salles @sallespro May 18 2015 21:32
@donnyhardyanto i have used Ah client in a web view and also connected with native android lib to AH with no problem. do you know what is not working ?
donnyhardyanto @donnyhardyanto May 18 2015 21:39
I tried to use AndroidAsync and Android Primus
But there is no response, or any activity on the action hero server (console)
@sallespro: what library do you use?
on Android
for web is working but web socket is not
salles @sallespro May 18 2015 22:05
https://github.com/koush/AndroidAsync is pretty good.
one should be aware of the room your connecting with the socket to have Ah show you the messages
salles @sallespro May 18 2015 22:24
i have used this native lib on Android https://github.com/saulpower/Android-Faye-Client
try _wellcome as faye’s main channel on Android
however, if i were going to do this today, i would stick with Primus as this is the socket lib AH is using nowadays.
donnyhardyanto @donnyhardyanto May 18 2015 22:44
I am finally able to get some response with Android Primus
salles @sallespro May 18 2015 22:45
what was missing ?
donnyhardyanto @donnyhardyanto May 18 2015 22:45
socket open
05-19 12:41:29.031 937-937/? V/Primus﹕ ["primus::ping::1432014089035"]
05-19 12:41:29.031 937-937/? D/Primus﹕ ACTUALLY SENDING: ["primus::ping::1432014089035"]
05-19 12:41:29.076 937-965/? V/Primus﹕ got string: {"status":"verb not found or not allowed","context":"response","data":null,"messageCount":11}
05-19 12:41:29.076 937-965/? V/Primus﹕ received something else
05-19 12:41:39.076 937-937/? V/Primus﹕
got this
on log cat
donnyhardyanto @donnyhardyanto May 18 2015 22:53
After reading Android Primus source code, finally can make Android Async start working
Do we must create ping for ws?
Evan Tahler @evantahler May 19 2015 00:22
It's usually required as most mobile carriers will disconnect idle connections after a few mins.
Sebastien Stettler @billybonks May 21 2015 09:18
anyone deployed actionhero app to heroku
and know of any gotchas
when i try start the app it cant find node_modules that are installed
Sebastien Stettler @billybonks May 21 2015 09:27
seems to be running the app in the wrong context
salles @sallespro May 21 2015 10:33
@billybonks there is a heroku button that might give a clue
Evan Tahler @evantahler May 21 2015 14:00
No gotchas. The main actuonhero project auto deploys to heroku (demo.actionherojs.com)
Evan Tahler @evantahler May 25 2015 05:39
@billybonks get it working?
Chad Robinson @crrobinson14 May 29 2015 04:54
Hey all. We're having an issue here ONLY in Dev where the process is exiting. All we get when this happens is >> Exited with code: 1. - no actual error message, reason, etc. We're having a hard time figuring out where this is actually happening. Any ideas?
Evan Tahler @evantahler May 29 2015 08:57
OOM might cause that
there are also a few places in the actionhero codebase where process.exit is a thing... but only in the binary wrappers.
if your app starts up OK, it sholdn't get there
SPOTI @spoti-io May 29 2015 08:59
Evan, is there a way to set custom http headers?
I tried to pass domain with nginx, like this proxy_set_header Host $http_host;
but host is never the original browser host
Evan Tahler @evantahler May 29 2015 09:33
absolutley!
data.connection.rawConnection.responseHeaders.push(['x-my-header', 'abc123'])
in your action or initilaize
r
interestingly, i JUST answered the same question on stackoverflow :D
http://stackoverflow.com/questions/30533528/actionhero-js-set-http-header/30533906#30533906
SPOTI @spoti-io May 29 2015 09:43
same team :)
Sebastien Stettler @billybonks May 31 2015 00:15
@evantahler ye i did, it was a case sensitivity issue :smile:
Chad Robinson @crrobinson14 Jun 04 2015 08:23
Has anybody had much luck with profiling?
We're tracking down a performance issue and struggling to get a good profile of the process. ActionHero doesn't seem to start properly when run as the usual "node --prof node_modules/.bin/actionhero" method.
Neil Craig @neilstuartcraig Jun 04 2015 08:30
i’ve not done anything much but dstat etc. looks like the way
there’s some good articles out there on the web
and you can pipe the output into a flamegraph
Chad Robinson @crrobinson14 Jun 04 2015 08:33
dstat doesn't look like a public tool. npm refers you to node-stat which is Linux-only.
Neil Craig @neilstuartcraig Jun 04 2015 08:34
dstat is open source
but you don’t get it on e.g. osx
i think the osx equivalent is truss
https://github.com/dagwieers/dstat
Chad Robinson @crrobinson14 Jun 04 2015 08:35
I'm really looking for something NodeJS aware. We don't believe this is something like excessive file I/O, it's a code bug. We're looking for JS-specific call graphs.
Neil Craig @neilstuartcraig Jun 04 2015 08:36
ah ok, in that case dstat won’t help you too much
Chad Robinson @crrobinson14 Jun 04 2015 08:36
We've had really good luck with Istanbul for code coverage, which annotates the code before running it. I was hoping for something similar in a profiler package.
Neil Craig @neilstuartcraig Jun 04 2015 08:37
have you tried new relic etc?
Chad Robinson @crrobinson14 Jun 04 2015 08:56
Yes, we use NewRelic and some home-grown Kibana-based QOS tools. That's how we know the transactions that have issues. But they don't home in on actual code.
Neil Craig @neilstuartcraig Jun 04 2015 08:59
yeah, they’re pretty high level aren’t they. i don’t personally know of anything further other than instrumenting your code with logs and timings but that could be time-consuming if the codebase is large/complex
Evan Tahler @evantahler Jun 04 2015 10:02
I've only had luck with heap dumps. I've never seen a good js profiler like the ruby kids have (skylight.io for example)
In actionhero it would be pretty easy to make a timing middleware for each action. Then you could log out the 1/5/10 min avg and counts.
Chad Robinson @crrobinson14 Jun 04 2015 10:05
That's actually a really good idea if anybody else is following this thread. We actually have this already and it helped us figure out which actions need the most attention in terms of optimization.
Evan Tahler @evantahler Jun 04 2015 10:05
Don't use the stats package, as it relies on redis
Make that middleware public!
Chad Robinson @crrobinson14 Jun 04 2015 10:05
I just wish node --prof worked - I can't figure out why it breaks everything. As soon as you start Actionhero with that, it just breaks everything.
Evan Tahler @evantahler Jun 04 2015 10:10
what happens when you try it?
(i've never used it)
Chad Robinson @crrobinson14 Jun 04 2015 10:11
Oddly, it varies. Sometimes it just hangs - you see actionHero>>> start and then nothing else.
Sometimes it makes it further before it dies. I'm not sure why.
Frequently it will die with error 139 - I'm not sure what would cause a SIGSEGV but...
Evan Tahler @evantahler Jun 04 2015 10:11
same here (node 0.12)
just hanging...
there's probably some c extension that freaks it out
Chad Robinson @crrobinson14 Jun 04 2015 10:12
I assume so.
Evan Tahler @evantahler Jun 04 2015 10:12
actually, I got it working
node --prof ./bin/actionhero start
add the "start" command
why that maters, I have no idea
Chad Robinson @crrobinson14 Jun 04 2015 10:14
Stop and start it and I bet it fails more often than it works.
About 1x in 10 tries I get it to work, although the profiles are junk
Evan Tahler @evantahler Jun 04 2015 10:14
ahh
and disable the websocket server
that helps
Chad Robinson @crrobinson14 Jun 04 2015 10:15
Oh
ws has a native C module doesn't it? ws is the primus default
Evan Tahler @evantahler Jun 04 2015 10:15
si
Chad Robinson @crrobinson14 Jun 04 2015 10:15
Actually I think it has two.
Evan Tahler @evantahler Jun 04 2015 10:15
still pretty crashy though
Chad Robinson @crrobinson14 Jun 04 2015 10:16
I found that last night debugging that WebSocket performance issue. We're srtill seeing huge data delivery delays where the request and AH processing time are just a few ms, but delivering the message to the user takes like 400+
Evan Tahler @evantahler Jun 04 2015 10:16
have you tried another transport, like primus?
Chad Robinson @crrobinson14 Jun 04 2015 10:16
I traced it all the way past AH, Primus, and into WS and had to stop there for the night. It's either in C code or Chrome
No, that's next.
Evan Tahler @evantahler Jun 04 2015 10:16
primus is great in that it gives you options, but I worry that the primus overhead might be high
Chad Robinson @crrobinson14 Jun 04 2015 10:17
We're trying to resolve a cascade failure where our actions are working, but not scaling. Like, literally 50tps is enough to kill a node - on pretty beefy hardware.
Evan Tahler @evantahler Jun 04 2015 10:17
what does that action do?
Chad Robinson @crrobinson14 Jun 04 2015 10:18
Various things, mostly simple tasks. Some are as simple as getting a Redis key (a data value we cache a lot) and delivering it in JSON. A simple GET request as a test.
1x request resolves in 7-12ms, consistently.
5x at a time, not bad, like 12ms-14ms
20x, and it's like 3 SECONDS
It just keels over.
We have a very large code base - it's not something we want to just take line by line. We were hoping for profiling to help find it but...
What's odd is it definitely seems to be WS related.
Evan Tahler @evantahler Jun 04 2015 10:19
yeah, that's pretty terrible
I was going to guess redis
Chad Robinson @crrobinson14 Jun 04 2015 10:20
I wonder if it's actually this layer, now that we're chatting about it. They could be related.
Evan Tahler @evantahler Jun 04 2015 10:20
perhaps a pooling issue
Chad Robinson @crrobinson14 Jun 04 2015 10:20
We think we ruled that out bceause HTTP requests are lightning-fast.
Evan Tahler @evantahler Jun 04 2015 10:20
ahh
sure
Chad Robinson @crrobinson14 Jun 04 2015 10:20
So...
Thinking about it, maybe there's a problem in that layer. We use WebSockets heavily but we don't have to - I can move transactions from one endpoint to the other easily. We have a client-side middleware layer like what actionHeroClient.js does but specific to our list of actions. I'll try that and report back.
Evan Tahler @evantahler Jun 04 2015 10:21
yeah, if HTTP is fast (with parallel connections), then it's got to be WS
i'd start by just changing from ws to something else
it should be really easy to do (very little code to cahnge on your end)
it migh also be your load balancer
i've seen many load balancers to crazy things with WS if not configured right
like... they think WS is a long-polling HTTP request, and have rules about only allowing so many at once, or only so many in that state anyway
i'm off
good luck!
Chad Robinson @crrobinson14 Jun 05 2015 09:09
Hey folks, what happened to connection.fingerprint? I just noticed after refaactoring to upgrade to the latest AH that it's null now for all my connections
Oh, weird. The Set-Cookie is configure for an expiration of 360000 but it's expiring immediately Set-Cookie:sessionID=8e0f2037694786fc39d235cdc2aeda1b33ea0409;path=/;expires=Fri, 05 Jun 2015 17:11:33 GMT;
That time is 1 minute ago in my local time
Chad Robinson @crrobinson14 Jun 05 2015 09:37
I saw the room handling middleware change and believe we implemented that correctly. Did anything change in fingerprint handling? When I join chat room topics I don't get what I used to (member list). I have code that relies on the fingerprint and I'm not sure why it's null all the time now.
Evan Tahler @evantahler Jun 05 2015 10:59
The connection moved to data.connection, but connection.fingreprint wmshkuld remain a thing.
Chad Robinson @crrobinson14 Jun 05 2015 14:19
OK, I got into this in a hunt for why chat room handling suddenly stopped working after our migration. We weren't passing the message payload to the say() callback - I sent a pull request to clarify the docs on this aspect.
We're still not getting fingerprints, no clue why
What I've noticed though is it only happens on dev boxes, where we use ports like http://localhost.firetalk.com:3000/
Without a port in the URL, it works. I've been all over Google and StackOverflow and everybody (specs, docs, devs) swears cookies don't care about ports. But IMO there's a Chrome bug here. AH sends the Set-Cookie and it's 100% properly formatted. But subsequent calls (or just repeating the original pattern after a reload) never send the cookie back to the server.
Our QA/Staging/Prod boxes don't use ports in the URLs, and they work fine - HTTP, HTTPS, doesn't matter. As long as it doesn't have :####. I have literally zero idea why this might be - it's the first time in my life I've ever seen this behavior. Calling it out here in case anybody else runs into it, since fingerprint is a useful tool in AH-land.
Evan Tahler @evantahler Jun 06 2015 11:07
That's super weird. Localhost should always come through.
Cookies absolutely care about ports
127.0.0.1:0 is not the same origin as 127.0.0.1:1
Depending on the strictness of the cookie
Evan Tahler @evantahler Jun 07 2015 15:28
@crrobinson14 ^
just like how localhost:80 is not the same as 127.0.0.1:80
Jacob Fike @jacobfike Jun 08 2015 15:21
Hey, I am seeing the following behavior with node-resque on AH v10.1.1
api-1 (err): 2015-06-08 13:28:09 - debug: Redis Connection Closed (client):
api-1 (err): 2015-06-08 13:28:09 - debug: connected to redis (client)
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (out): 2015-06-08 13:28:09 - info: resque scheduler started
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): 2015-06-08 13:28:09 - debug: started: resque /vagrant/src/node_modules/actionhero/initializers/resque.js
api-1 (err): (node) warning: possible EventEmitter memory leak detected. 11 start listeners added. Use emitter.setMaxListeners() to increase limit.
api-1 (err): Trace
api-1 (err): at addListener (events.js:179:15)
api-1 (err): at /vagrant/src/node_modules/actionhero/initializers/resque.js:27:28
api-1 (err): at /vagrant/src/node_modules/actionhero/node_modules/node-resque/lib/scheduler.js:25:43
api-1 (err): at /vagrant/src/node_modules/actionhero/node_modules/node-resque/lib/queue.js:20:41
api-1 (err): at /vagrant/src/node_modules/actionhero/node_modules/node-resque/lib/connection.js:81:11
api-1 (err): at try_callback (/vagrant/src/node_modules/actionhero/node_modules/redis/index.js:592:9)
api-1 (err): at RedisClient.return_reply (/vagrant/src/node_modules/actionhero/node_modules/redis/index.js:685:13)
api-1 (err): at ReplyParser.<anonymous> (/vagrant/src/node_modules/actionhero/node_modules/redis/index.js:321:14)
api-1 (err): at ReplyParser.emit (events.js:107:17)
api-1 (err): at ReplyParser.send_reply (/vagrant/src/node_modules/actionhero/node_modules/redis/lib/parser/javascript.js:300:10)
It seems to be creating a new worker every time it gets disconnected/reconnected to redis, but is not cleaning up the old workers, so every iteration there is 1 more worker than last time.
Is this a known issue with AH, or is it a node-resque problem?
Evan Tahler @evantahler Jun 08 2015 23:50
That seems like the correct behavior if you are constantly loosing connection to redis. The app keeps trying to work, and there's no way to know the state of a disconnected worker.
There are some docs in node-resque about cleaning up "lost" workers, but they are dangerous so AH doesn't implement them
salles @sallespro Jun 08 2015 23:58
when we kill an AH process, the next restart cleans the workers doesn’t it ?
Evan Tahler @evantahler Jun 09 2015 00:01
If it's on the same server, and that server has fixed identifiers (like IP address) then yes
If you are on a PAAS like heroku, or sometimes even vagrant (like the example) potentially not
But again, that's the limit of "safety" that can be guaranteed
Siddique Ahmad @SiddiqueAhmad Jun 09 2015 02:37
which channel i should subscribe, if want to monitor actionhero chat system,
i am using php and want to send message via php using redis pubsub
Siddique Ahmad @SiddiqueAhmad Jun 09 2015 02:48
got it
Evan Tahler @evantahler Jun 09 2015 03:42
The subsribtion logic is handled here https://github.com/evantahler/actionhero/blob/master/initializers/redis.js#L110-L137
and the chanel is set by api.config.redis.chanel
everything in actionhero is on one channel, say included
we send JSON'd messages around, which have a messageType https://github.com/evantahler/actionhero/blob/master/initializers/chatRoom.js#L41-L52
Siddique Ahmad @SiddiqueAhmad Jun 09 2015 03:54
thanks @evantahler
Chad Robinson @crrobinson14 Jun 10 2015 11:20
@evantahler No, we know cookies care about ports. But cookies aren't WORKING on localhost ports - at all. Chrome docs and forum posts say they should, but if we add hosts entries like "localhost.myapp.com" and access via "http://localhost.myapp.com:3000", Set-Cookie looks right, but future requests to that URL do not include its contents as a Cookie header.
This only seems to apply on localhost.
It works fine on any host that is not also 127.0.0.1, and seems to be limited to Chrome (although we use that heavily for Dev so it's frustrating).
Jacob Fike @jacobfike Jun 10 2015 11:26
Actually, I think I interpreted the error wrong. It's actually re-attaching event listeners (start, stop, etc) every time, and the number of listeners it attaches is growing. So in the log output I provided, it attached 11 start listeners for a single worker. That doesn't sound like a good idea. In fact it appears to be running the resque initializer multiple times based on those log messages.
Evan Tahler @evantahler Jun 17 2015 01:30
so... any cool new projects over here?
Greg Coonrod @gcoonrod Jun 17 2015 07:46
So many ideas, so little time.
Evan Tahler @evantahler Jun 17 2015 10:10
Haha. That's how it is.
salles @sallespro Jun 17 2015 18:00
time is on your side
Chad Robinson @crrobinson14 Jun 19 2015 09:50
http://Firetalk.com will go public at VidCon July 20th
Evan Tahler @evantahler Jun 19 2015 12:00
Ooh!
Siddique Ahmad @SiddiqueAhmad Jun 23 2015 01:06
@evantahler is there any already plugin or help i can get on guaranteed message delivery, like if subscriber went offline, and i want to delivery offline messages when he came back,
refer me to help link or any idea will work
Evan Tahler @evantahler Jun 23 2015 05:53
no. That's very dependent on your infrastructure and where you want to store those messages. Small volume, high value messages? Use a relational store with a "delivered" column. High volume? Use a cluster'd noSQL database like Riak or Elasticsearch (and you'll need to deal with duplicae delivery on the client)
Siddique Ahmad @SiddiqueAhmad Jun 24 2015 01:42
okay, planning to use sync gateway of couchbase
Alexandru Stanciu @alexstanciu Jun 24 2015 01:53
sync_gateway works good if you build mobile apps ... for web you have to use pouchdb with sync_gateway witch is not stable. The alternative is firebase, it works on all envs
Siddique Ahmad @SiddiqueAhmad Jun 24 2015 01:55
ya you are right, currently i need this for mobile app,
Evan Tahler @evantahler Jun 24 2015 03:37
I mean, you can also just store messages in Redis and pop them as the users's show up
Alexandru Stanciu @alexstanciu Jun 26 2015 02:25
Hello guys! I need an advice regarding tasks. I'm planning to create a task to record livestreams to VOD files.
I will use http/socket/websocket(one of those, I don't know for now wich one) call to "start recording" & "stop recording".
based on what it does, I decided to make it a task. For stream dump I use livestreamer.io CLI. The problem is that sometimes a stream goes offline because of user (who streams) connection issues or others.
The plan is to somehow check from time to time if the stream is back online if the "stop recording" command was not issued. Because livestreamer stops when the stream is offline, the dump to vod file will end and my "spawn" will end also.
I'm thinking to restart the task somehow when stream back online and when I receive "stop recording" I will need to use ffmpeg or something similar to merge all VODS together for this stream after I receive end command.
Please let me know if you have a better solution for this, or better aproach. Thanks
Siddique Ahmad @SiddiqueAhmad Jun 26 2015 02:58
the new version of sync gateway providing web hooks, so i can push messages too, or any task can be done, no need to use feeds long polling
Neil Craig @neilstuartcraig Jun 26 2015 13:56
@dangerdespain I just spotted a couple of articles (haven’t tried them yet but they look very promising) on profiling CPU usage in node:
http://www.brendangregg.com/blog/2014-09-17/node-flame-graphs-on-linux.html
http://thlorenz.com/flamegraph/web/
I recall @crrobinson14 also wanted the same sort of thing, maybe they’re of some interest? just thought i’d pass on the links in case you didn’t find them
Chad Robinson @crrobinson14 Jun 26 2015 17:19
@alexstanciu We've built a whole platform for managing what you're describing for Firetalk, and that's more or less what we do - after a stream has stopped, if there were discontinuities you need to fill or mend them. But it's not really an ActionHero topic...
@neilstuartcraig We are definitely interested this and plan to play with the flame graphs literally next week - we were a little busy this week with all kinds of last-minute pre-code-freeze stuff for our public launch. :)
Neil Craig @neilstuartcraig Jun 26 2015 22:38
@crrobinson14 Nice! It'd be great to see how you get on. I'm planning on looking at it to but have a backlog of other stuff too.
Evan Tahler @evantahler Jun 27 2015 08:01
Yeah! Share what you learn! I'm curios tok
Too
Siddique Ahmad @SiddiqueAhmad Jul 02 2015 11:17
silence is golden
Evan Tahler @evantahler Jul 02 2015 16:30
Ha
Alexandru Stanciu @alexstanciu Jul 03 2015 23:13
silence means nobody is working, everybody has fun :)
omichowdhury @omichowdhury Jul 07 2015 15:20
or everyone is having fun working :+1:
Alexandru Stanciu @alexstanciu Jul 07 2015 23:46
is there a way to detect "in" task when it has been deleted / stopped ? api.tasks.del(queue, taskName, args, count, next). Something like onDelete. I want to execute some code before stopping the task
Evan Tahler @evantahler Jul 08 2015 00:46
Nope. But you can write a node-resque plugin for this
I think
Alexandru Stanciu @alexstanciu Jul 08 2015 00:46
Ok. Thanks
DefunctExodus @DefunctExodus Jul 08 2015 05:24
Having fun migrating from python to node. Really dig this framework.
Evan Tahler @evantahler Jul 08 2015 08:00
Cool!
Chad Robinson @crrobinson14 Jul 13 2015 08:15
Does anybody have a good way to maintain a viewer count across chat rooms?
We're struggling to get this "right". We want to persist a value in our DB as an analytic, but prefer to do it server side.
We started out with enter/leave incrementing/decrementing a counter but we found too many edge cases where it got out of sync, things like if your server node dies because of a bug - all those connections drop but don't get decremented.
Evan Tahler @evantahler Jul 13 2015 09:25
Redis ttl and client heartbeats
Set a key like client_(id) and ttl it to 1 min
Have each client then hear eat every 20 s
This is also a simpke way to keep state data about clients (active, idle, etc)
It's hard to do purely server side because of client re connection events too
Changing nodes, etc
Actually for you, the key names would be client-(room)-(Id)
Then just count the keys matching the prefix
Chad Robinson @crrobinson14 Jul 13 2015 10:12
We did something similar. In a setInterval (not a task, has to run each node) we iterate api.connections.connections every 20-30s or so. We get a per-node count of its room members (like system: 3, otherroom: 2, ec.) and set a redis key like ourapp:system:NODEID = 3.
Then in a task every 30-60s we get all those keys, sum them, and write the per-room totals to the DB
I just didn't know if there was a better way
Evan Tahler @evantahler Jul 13 2015 10:43
nah, not that I can think of. The trick is that TTL so the keys die off soon after the connection goes away
not that I can think of.
This message was deleted
Amine Mouafik @kytwb Jul 15 2015 04:00
When running api.commands.stop I get:
api_1 | Unhandled rejection TypeError: Cannot read property 'running' of undefined
api_1 | at Object.actionhero.stop (/app/node_modules/actionhero/actionhero.js:234:14)
api_1 | at null.<anonymous> (/app/initializers/migrations.js:17:22)
api_1 | at tryCatcher (/app/node_modules/bluebird/js/main/util.js:26:23)
api_1 | at Promise._settlePromiseFromHandler (/app/node_modules/bluebird/js/main/promise.js:489:31)
api_1 | at Promise._settlePromiseAt (/app/node_modules/bluebird/js/main/promise.js:565:18)
api_1 | at Promise._settlePromises (/app/node_modules/bluebird/js/main/promise.js:681:14)
api_1 | at Async._drainQueue (/app/node_modules/bluebird/js/main/async.js:123:16)
api_1 | at Async._drainQueues (/app/node_modules/bluebird/js/main/async.js:133:10)
api_1 | at Immediate.Async.drainQueues [as _onImmediate] (/app/node_modules/bluebird/js/main/async.js:15:14)
api_1 | at processImmediate [as _immediateCallback] (timers.js:358:17)
This message was deleted
Not sure if that's fixed in newer version, we didn't updated AH for past weeks
Evan Tahler @evantahler Jul 15 2015 04:23
What version? We did fix that a few months ago
evantahler/actionhero@b3a5ff3
Alexandru Stanciu @alexstanciu Jul 16 2015 15:31
trying to broadcast a message in chat room and I get:
roomAdd main
{"status":"OK","context":"response","data":true,"messageCount":1}
roomAdd main
{"status":"connection already in this room","context":"response","data":false,"messageCount":2}
roomView main
{"status":"OK","context":"response","data":{"room":"main","members":{"5c979770-eb52-44a0-8587-28b593aed7e8":{"id":"5c979770-eb52-44a0-8587-28b593aed7e8","joinedAt":1437085632983}},"membersCount":1},"messageCount":3}
say {room : "main", message : "some test message"}
{"status":"connection not in this room","context":"response","messageCount":4}
Amine Mouafik @kytwb Jul 17 2015 01:43
@evanthaler: no biggy, probably our fork's not up-to-date
btw. I released ah-hipchat-plugin so you can take it if you want for https://github.com/evantahler/ah-hipchat-server-plugin
Evan Tahler @evantahler Jul 17 2015 04:41
I don't understand the hipchat comment above
I made that one
Evan Tahler @evantahler Jul 17 2015 10:23
@alexstanciu what's the issue?
oh...
did you first connection.roomAdd() ?
Alexandru Stanciu @alexstanciu Jul 17 2015 10:24
yes, roomAdd main. also main exists in default rooms
Evan Tahler @evantahler Jul 17 2015 10:42
?
can you provide a fuller example?
Alexandru Stanciu @alexstanciu Jul 17 2015 10:50
@evantahler in api config i added room "main" after that I just connected with 2 telenet sessions to host:5000 - didn't touched anything from default configs in ah. The problem is that when I use say command I receive that {"status":"connection not in this room","context":"response","messageCount":4} even if I use roomAdd main. Do I do something wrong?
Evan Tahler @evantahler Jul 17 2015 11:06
seems OK?
> telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"welcome":"Hello! Welcome to the actionhero api","context":"api"}
randomNumber
{"randomNumber":0.9095923991408199,"context":"response","messageCount":1}
roomAdd room2
{"status":"OK","context":"response","data":true,"messageCount":2}
say room2 hello there
{"status":"OK","context":"response","messageCount":3}
{"message":"hello there","room":"room2","from":"2a7e4b22-45e5-49d0-b820-b8e48d52eeeb","context":"user","sentAt":1437156407540}
Alexandru Stanciu @alexstanciu Jul 17 2015 11:09
thanks @evantahler I was sending params as json say {room : "main", message : "some test message"}
Alexandru Stanciu @alexstanciu Jul 17 2015 14:44
@evantahler is there any way to push a CustomLogger? I plan to store log in mongo database. I have the connection trough initialiser api.mongodb.db. The plan was to do a custom winston transport for this. After checking AH config and initializer for logger I saw you "inject" them trough config (console & file). The configs are loaded before initializers, right? Any idea how I add custom logger transport for this in witch I can access mongodb instance? Thanks
Evan Tahler @evantahler Jul 17 2015 16:07
Just make your logger in the configure files
Alexandru Stanciu @alexstanciu Jul 18 2015 00:14
Thanks @evantahler . Is kinda ugly in there, but at least is working :)
Amine Mouafik @kytwb Jul 18 2015 02:49
@evantahler sorry, by released I meant I unpublished ah-hipchat-plugin on npm so you can use the name for your plugin.
Evan Tahler @evantahler Jul 18 2015 10:36
Oh, yay!
Ty
Devin Despain @dangerdespain Jul 20 2015 01:03
@neilstuartcraig Hey thanks! Just saw those articles. I ended up using the heapdump library on Node v12 with Chrome's memory profile analyzer
it's the only combination I could get to play nicely without banging my hard too head against the walls
Oughtta do a writeup of that if I ever go through that process again
I was too frustrated the first time ;)
Neil Craig @neilstuartcraig Jul 20 2015 01:06
Ah nice @dangerdespain . A write up would be great. I'm really interested in it too. Going to try to get around to it in a few weeks.
Devin Despain @dangerdespain Jul 20 2015 01:11
awesome
honestly, just give that above combination a shot
who knows, it might work the first time!
Neil Craig @neilstuartcraig Jul 20 2015 01:20
Did you get much useful data out?
Devin Despain @dangerdespain Jul 20 2015 01:26
CPU profiling worked great
http://tinypic.com/r/1zw16dg/8
the UI is a little clunky but with creative sizing and hovering, data can be had
didn't have as much luck with memory profiling, which was where the issue ended up being afaik
someone else tackled the problem on that end
Neil Craig @neilstuartcraig Jul 20 2015 01:39
Cool. Well that's good news it its own right. I'll try it as soon as I get the time. Just got some migrations of plugins to do from ah 10 to 11. Then I'll get on to it.
Devin Despain @dangerdespain Jul 20 2015 01:40
good luck! Can't guarantee I can help but give a shout if you run into anything
Neil Craig @neilstuartcraig Jul 20 2015 01:40
I wonder how different iojs is. I'm running 2.3 currently. I know the chrome team have been adding more hooks in to v8
Evan Tahler @evantahler Jul 20 2015 05:48
yeah! please add a writeup!
AKA, I'm lazy and want to do it too :D
Evan Tahler @evantahler Jul 20 2015 05:57
Hey @crrobinson14 I think you said today was launch day... good luck!
Evan Tahler @evantahler Jul 20 2015 07:30
https://groups.google.com/forum/#!topic/actionhero-js/miMKe86x9so
new version
Now in chat middleware, you can use register onSayReceive middleware. This will let you inspect/modify the message once (as it is sent in) rather than the say middleware which will be invoked once per client connected to the room. In many cases, this might be more efficient.
Evan Tahler @evantahler Jul 20 2015 09:22
Another new version: This one fixes a long-standing bug with how action responses are rendered before the WS connection succeeds.
Amine Mouafik @kytwb Jul 21 2015 00:58
Hey there :) We have authenticated endpoint we'd like to access through the websocket server. Usually, we just put our jwt token in the authorization header (when making http requests); but I wanted to know if you guys had any ideas on how to use that auth system with websocket? I can make a request to the auth endpoint through the websocket to get a token, but then I don't know
Just throwing it here in case, going to start digging my own way now in //
Evan Tahler @evantahler Jul 21 2015 01:33
Have an auth action that sets connection.authebticated = true on the server. Then, it's really easy to check, and the client has no extra work to do
Just send that token up once
Amine Mouafik @kytwb Jul 21 2015 02:45
:+1:
Devin Despain @dangerdespain Jul 23 2015 23:26
alright - I've got a couple projects on the top of my head and wanted to get some community input before diving into things too deeply
1 - A development feature that will add the plugin directories to the auto-reboot file watcher (configurable)
2 - A development feature that would override the action "run" method and return the example response object instead
for quick front-end prototyping with psudo-functional actions :+1:
Evan Tahler @evantahler Jul 24 2015 06:22
1 I like a lot
2 is wierd for me personally because I often don't know what my response payload will look like until I'm done with the action
I think 2 feels more like a boot flag than a config option
like MOCK_RESPONSES=true NODE_ENV=development npm start
Onfire7 @Onfire7 Jul 24 2015 21:39
Having used apiary.io to prototype my api's before, a bootflag for returning the examples would be awesome!
It makes development with more than one person a lot easier when you can just agree on an api, and the front end guy(s) can build stuff to work with the real api without having to wait on all of the actions to be finished. (Coming from a project with 130+ actions and we aren't even done yet...)
Devin Despain @dangerdespain Jul 24 2015 22:16
That's along the lines of what I was thinking - a quick API blueprint. It would actually be easy to implement in a high-priority middleware preprocessor. Any preference on this being a core feature vs a plugin?
Evan Tahler @evantahler Jul 25 2015 00:31
Start with A plugin. If people
love it we can move it to core
Branie @BransonGitomeh Jul 26 2015 03:07
@evantahler hey i just started using action-hero yesterday with ember.js and this is an awesome job
regarding api's Json Api Spec hit 1.0 recently and its pretty awesome
i don't really know action-hero that well but
1.can you make a tutorial to make all responses in action-hero compliant to the spec?
2.make a plugin or move it to core
ember -data(a client-side data persistence lib) has a large user-base in the ember community and it works with JSON API out of the box
both ember and actionhero share alot of "opinions" on structure, tools are almost similer ie Ember-cli and ember has some big companies using it with ember data so i think having having either an awesome tutorial or a plugin or to-core :-p implementation of json-api would be a win-win for both communities
Json Api Spec at 1.0
Branie @BransonGitomeh Jul 26 2015 03:19
or something like this
sails101/contribute-to-sails101#3
Evan Tahler @evantahler Jul 26 2015 04:51
Can you open an issue for this? Some other folks just made a swagger plugin, and this seems sinilar
Similar
Can you also give some examples of other frameworks that use this spec, so we have examples
salles @sallespro Jul 26 2015 07:34
@BransonGitomeh those who have ideas have also the priviledge to implement them first and are self defyed to do so. please share your experience with Ember client and JSON API spec in its awesomeness through your eyes.
@evantahler is the swagger plugin just about the docs ?
Evan Tahler @evantahler Jul 26 2015 07:42
Check it out
https://www.npmjs.com/package/ah-swagger-plugin
Amine Mouafik @kytwb Jul 26 2015 22:51
Nice
Branie @BransonGitomeh Jul 28 2015 01:56
@sallespro @evantahler i think my idea is awesome but it was wrong for me to try and contribute after just a short time of a simple app, i think it'll be better if i get familiarize with your framework first so i can give concrete contributions that align with the entire view-point of the whole community, here instead of just things that only align with my needs as a developer, sorry
salles @sallespro Jul 28 2015 04:10
@BransonGitomeh ideas are born just like that, and it’s very nice ( not wrong ) to speak freely about it. Of course there’s a context one might be better of getting to know to shape it afterwards.
Also, open source is great because you’re not tied to an “entire” view point, but free to develope your own, taking advantage of this great possibility to share and learn.
thanks for your concrete contribution ! but remember, when ideas are born, they need to be nurtured, a its “father” is responsible and priviledged to do it, preferably, with a community support.
Evan Tahler @evantahler Jul 28 2015 07:52
I like that we are getting philosophical in here!
Greg Coonrod @gcoonrod Jul 28 2015 09:36
Is there a way to pause task processing on a specific queue?
Evan Tahler @evantahler Jul 28 2015 10:29
stop the workers?
workers are defined to work a collection of queues ['fast_jobs', 'slow_jobs']
so you can stop workers, and then start them up again with a reduced set of queues to work
you could also write a middleware that checks the job's queue agsinst a "to work" list in redis or something like that
Alexandru Stanciu @alexstanciu Jul 28 2015 10:31
tasks support middlewares?
you mean making another task for checking?
Evan Tahler @evantahler Jul 28 2015 10:37
Rescue supports plug-ins.
Check out the node-rssque project
Alexandru Stanciu @alexstanciu Jul 28 2015 10:37
ok, got it
Evan Tahler @evantahler Jul 28 2015 10:38
And you define which plug-ins you want within action hero at the task definition.
Greg Coonrod @gcoonrod Jul 28 2015 10:39
Thats what I was afraid of :)
Evan Tahler @evantahler Jul 29 2015 04:03
haha
let me know if you need help
there's also a node-resque gitter chat
https://gitter.im/taskrabbit/node-resque
Docs -> https://github.com/taskrabbit/node-resque#plugins
Greg Coonrod @gcoonrod Jul 29 2015 06:20
How does one ensure that the task processors are running during a test?
I've already copied the relevant parts out of the default tasks.js config but I'm still not seeing tasks being handled.
salles @sallespro Jul 29 2015 09:33
how can one build an Actionhero API that allows third party plug-ins adding new routes/actions hot loading ?
Greg Coonrod @gcoonrod Jul 29 2015 09:47
Hot load? As in new routes created dynamically during run time?
Evan Tahler @evantahler Jul 29 2015 09:53
@sallespro that's what plugins are for!
http://www.actionherojs.com/docs/core/plugins.html
@gcoonrod here's an example from actionhero's tests
https://github.com/evantahler/actionhero/blob/master/test/core/tasks.js#L252-L263
note the call to api.resque.multiWorker.start()
(and be sure to stop it as well)
Greg Coonrod @gcoonrod Jul 29 2015 09:56
@evantahler Thanks! Though I figured out my problem. There was a logical error in some of my code (surprise surprise).
Evan Tahler @evantahler Jul 29 2015 09:56
... and that is why you test!
Greg Coonrod @gcoonrod Jul 29 2015 09:58
Have you given much thought to Task orchestration? Task dependency management has become a major focus of my development work for the past few months. I'm wondering how others are dealing with that.
Evan Tahler @evantahler Jul 29 2015 10:03
what do you mean? Like a fan-out of tasks/events?
if so, check out https://github.com/queue-bus/node-queue-bus
this ads a pub-sub layer on top of node-resque
it's not integrated into actionhero
but I've used it in a few projects (and in other languages http://tech.taskrabbit.com/blog/2013/09/28/resque-bus/ ) and it works pretty well
Greg Coonrod @gcoonrod Jul 29 2015 10:09
Sort of, I work with a lot of tasks that need to run only after other tasks have completed successfully. I build large chains of tasks with interdependencies and then ensure that the entire chain executes in order.
salles @sallespro Jul 29 2015 10:24
@evantahler i am trying to figure out this in a production environment where i have a running instance of AH i wish to keep running. then i create another instance with the plugin enabled…i am not sure how to join the cluster with the new plugin.
Evan Tahler @evantahler Jul 29 2015 10:30
@gcoonrod I tend to approach those things with a state macine
store the state in a DB
and after each step fire off a new task
this way you can interject and observe each step along the way
and if it fails, you have gotten "some of the way"
Greg Coonrod @gcoonrod Jul 29 2015 10:30
Thats exactly what we're doing. We have an initializer that acts as orchestrator.
Evan Tahler @evantahler Jul 29 2015 10:31
cool
Greg Coonrod @gcoonrod Jul 29 2015 10:31
And we save the state in redis
Roll back is still an issue right now. And we've run into some really fun race conditions.
Evan Tahler @evantahler Jul 29 2015 10:33
if you are modifying a single object along the way
this might be a great place to use a resque-lock plugin
aka: only one job can "claim" an object at a time, and if someone else has it, re-enqueue myself for later
Greg Coonrod @gcoonrod Jul 29 2015 10:34
Hmm, that might be useful. We're doing ETL work essentially.
Evan Tahler @evantahler Jul 29 2015 10:34
https://github.com/taskrabbit/node-resque/blob/master/lib/plugins/jobLock.js
on an unrelated note, I am writing a node ETL framework right now
I'll publish it out in a month or so
Greg Coonrod @gcoonrod Jul 29 2015 10:35
Need a beta tester?
Evan Tahler @evantahler Jul 29 2015 10:35
I'm pretty happy with it, but it has nothing to do with actionhero
taskrabbit.com is the beta tester
Greg Coonrod @gcoonrod Jul 29 2015 10:36
nice
Evan Tahler @evantahler Jul 29 2015 10:42
in general, I've had poor experiences with "defered objects" with ETL work, and tend to work with defered steps
like
the step "extract source A into B" needs to happen in waterfall
but the tables in A moving to B can happen in any order (parallel)
so the resque model of priority doesn't really hold for me
I've gone the way of "pages" and "chapters"
chapters happen in series, pages in parallel
@sallespro I don't think I understand the question
Greg Coonrod @gcoonrod Jul 29 2015 10:45
Thats very similar to the approach we're taking. We're making paged calls to external systems in parallel where each call is encapsulated in a AH task. Our task orchestrator manages the fanning out and collapsing of those task chains.
salles @sallespro Jul 29 2015 10:49
the question is how to inlcude another AH instance with a new plugin into a running cluster.
is it like deploying a new commit and restart ?
or add a new instance under a load balancer that has the new plugin ?
the end goal is to allow a third party developer to “publish” this modules into a running API.
Evan Tahler @evantahler Jul 29 2015 10:54
a plugin is code. It's problably included via NPM as an installed package that is required in the project
you'll likley need to redeploy and restart however you do that now
salles @sallespro Jul 29 2015 10:55
what is happening when we see in AH that another instance was added to the cluster ?
Evan Tahler @evantahler Jul 29 2015 10:56
on boot, actionhero publishes to redis that "I'm here"
other nodes, when seeing that message log it out
that's pretty much it though
you can hook into those messages in your code
but right now they don't do much of anything other than log
salles @sallespro Jul 29 2015 11:02
once hooked, how can new routes/actions be made available ?
how do we scale and add new routes ?
Greg Coonrod @gcoonrod Jul 29 2015 11:05
can you use api.routes.registerRoute()?
Evan Tahler @evantahler Jul 29 2015 11:09
that's one way, sure
you can also rely on the auto-generated action names
of just mess with api.routes.routes directly
(which is a hash)
https://github.com/evantahler/actionhero/blob/master/initializers/routes.js#L6
Onfire7 @Onfire7 Jul 29 2015 13:41
So, I am working on a project that y'all might find interesting, and I would welcome any ideas/how you would do it that/comments that you might have.
I'm trying to create a smart API client for AH (preferably as a plugin) that will:
Communicate with AH over websockets
Authenticate with an API token
Generate a list of functions to run actions that the key is authed for
Automatically understand links to related information and prefetch as necessary
Keep information that actions return up to date automatically, preferably without re-running the action
Basically, I want something that can be dropped in a project, and using minimal effort be able to get data from whatever actions you have that is automatically kept up to date.
I currently have a prototype that's (mostly) working, but I would like to see what thoughts y'all have on this before I start working on something proper.
Evan Tahler @evantahler Jul 29 2015 14:14
We've got a true duplex socket client you can take a peak at
Server - server
https://github.com/evantahler/actionhero-client
Sounds like you want to almost make a WSDL?
Greg Coonrod @gcoonrod Jul 29 2015 14:16
shudder
Onfire7 @Onfire7 Jul 29 2015 14:26
Sorry, I guess I should have clarified that. It's a client library for a webpage, and a set of actions to support it.
The end result would be very similar to how ah-sdk-angular generates Angular services for your actions. (And in fact an angular service wrapper will be made for this.)
But taking Googles approach of generating the functions to access the api client side, (rather then server side, or in advance) and the actions response would be kept up to date automatically.
With ah-sdk-angular you add the plugin, and then it generates a file that you include in your Angular project that has a service for each action. Then you just plug in the services that you need to use for a page and you can get data from your actions.
I want to have the same "just drop it in and start using your actions" ease of use but with the ability to have data that your actions return to be updated when something changes it.
Evan Tahler @evantahler Jul 30 2015 00:48
I guess I don't understand the point. Why generate functions at all? How is that better than just calling client.action('theAction)
Vs client.actions.theAction()
Onfire7 @Onfire7 Jul 30 2015 01:33
Function calls are just for readability, and as a simple way to test for available functionality without causing a server call.
The point of the client as a whole however, is to be able to update data as it changes, without having to manually handle it. Currently this involves a fair amount of orchestration between your actions having to explicitly fire off change messages to clients, and your page parsing change notifications and doing something about it. While this isn't a huge deal of work for some projects, when working with a lot of large projects, it gets tedious and somewhat error prone to handle this. So the goal is to have something with a simple way for actions to communicate what they are effecting, and to push the changes to clients that are actively using that data, or expecting to be using it soon.
So, you do something like client.actions.get_comments(post_id, function(res){ /* Insert or Update your comments */});
And then when this is called client.actions.post_comment(params, ...) the first function runs again with the updated data. (With intelligent caching behind the scenes, so that only the new comment, and a new list of comments is sent, rather then the entire contents of all of the comments.)
Onfire7 @Onfire7 Jul 30 2015 01:44
It's definitely not something that would be suitable for all projects, but the goal is to have something to handle the times when you just want to be able to call an action, and then know that whenever something changes, your callback will run again with up to date info.
Alexandru Stanciu @alexstanciu Jul 30 2015 09:07
@Onfire7 why not use websockets for this? You can trigger "comment updated". I think you can make a service for it and use 2way data binding
Onfire7 @Onfire7 Jul 30 2015 11:22
@alexstanciu Currently we do, through the Actionhero client library, and in fact the library I am building now is just a high level abstraction on top of the Actionhero client. The only thing is, we have 130+ actions with 5+ websites using different groups of actions to show different views of the same data. That's a lot of things to write message handlers for on top of handling the actions response, and a lot of potential for bugs that could easily be fixed by abstracting it all away so that you only handle the actions response, and the messages are handled automatically, rerunning your callback with a freshly constructed copy of your data.
Evan Tahler @evantahler Jul 30 2015 14:53
I guess we'll just have to see it in action then! Good luck, and keep us posted!
Always ask for help here or on the mailing list
Btw. What are you making?
Onfire7 @Onfire7 Jul 30 2015 15:37
I work at a church that runs a school during the fall, winter, and spring, with around 200 students and a summer camp that averages 20,000 campers per year in 2 months, with often around 1,000 campers at any one time. Needless to say, a lot goes into keeping everything moving at that kind of scale.
So we have our internal operations department that has several stations that handle things like incoming information, actions that need to get done, events that are going on, etc. So they are constantly sending information back and forth between the stations.
Then we have our Guest Services department that receives information from operations. (Restroom needs cleaning, spill, maintenance request, etc. )
We also have our registration department to help register people as they get here, which involves them going to a few stations for different parts of the process.
We have a site for the kitchen to handle meals, and staff/student websites, that gives us various information and allows us to signup for things.
And it's all integrated so that, for example:
The kitchen can see how many people are registered so that they know how many meals to prepare.
When registration puts contact information for people in the system, operations has access to it.
Operations can see how many people are staying in each building.
Etc.
salles @sallespro Jul 30 2015 15:42
cool use case to manage the meals. but, as pink floyd once said, leave them kids alone...
Alexandru Stanciu @alexstanciu Jul 31 2015 06:35
cool @Onfire7
Evan Tahler @evantahler Jul 31 2015 06:56
cool.
Chad Robinson @crrobinson14 Jul 31 2015 11:54
Just in case anybody is curious, https://firetalk.com/ officially launched last week at VidCon. Core API is ActionHero. We're only just getting started but we've already managed 4000 simultaneous users online, text chatting and using other things we built with the app/API.
We're very happy with it so far.
One (amusing) lesson learned.
It's "actionhero startCluster" not "actionhero --startCluster". ActionHero scales way better with the first command.
Chad Robinson @crrobinson14 Jul 31 2015 12:09
@Onfire7 We solved some of the challenges you mentioned above (intelligently propagating server-sourced changes through a client-side UI, incrementally) by just using AngularJS (React is nice too - it just wasn't as nice when we started on this project last year). Now that they've sorted out the digest-cycle performance concerns, it's amazingly performant, and there's zero tedium in updating UIs. I'd hate to ever have to do it the old way again.
Devin Despain @dangerdespain Jul 31 2015 13:40
is there an AH version hidden somewhere inside the api object?
api.actionheroVersion returns the API version, not the Actionhero version -- is this the expected behavior?
for context - I'm updating a couple plugins to be cross-compatible with the two different versions of AH that I'm running for separate projects
Evan Tahler @evantahler Jul 31 2015 14:25
Congrats on the launch!!
I think you have that backwards. http://demo.actionherojs.com/api/status
ActuonheroVersion != serverInformation.apiVersion
Devin Despain @dangerdespain Jul 31 2015 14:31
these objects are getting the best of me today
must be Friday ;)
thanks @evantahler!
Chad Robinson @crrobinson14 Aug 03 2015 07:28
@evantahler What do you think about emitting an error on unrecognized parameters to stop other people from doing what we did (using --startCluster instead of startCluster?) I could send a PR if you want.
Evan Tahler @evantahler Aug 03 2015 14:45
Sure! PR it in!
Greg Coonrod @gcoonrod Aug 04 2015 12:31
@evantahler Do we have any hooks to the resque workers from within an AH task?
Evan Tahler @evantahler Aug 04 2015 14:47
Other than the events, I dint think so.
Greg Coonrod @gcoonrod Aug 05 2015 08:57
When adding tasks to dynamic queues I'm noticing that workers don't seem to pick tasks from the new queues for long periods of time. Has anyone else run into that?
Evan Tahler @evantahler Aug 11 2015 10:55
new version up!
https://github.com/evantahler/actionhero/releases/tag/v11.5.0
Amine Mouafik @kytwb Aug 11 2015 12:03
that's awesome! :thumbsup:
Victor Heng @bakavic Aug 13 2015 03:51
noob qns - does AH support arrays as action inputs? Only way I think this would work now would be to set api.config.general.disableParamScrubbing to false?
Neil Craig @neilstuartcraig Aug 13 2015 04:34
Hi @bakavic. I’m not sure it does but you could stringily/serialise the array before sending and de-stringify/serialse in the action.
Evan Tahler @evantahler Aug 13 2015 05:34
@bakavic that's a bit of a complex question. First off, technically, there are no "types" in a web request
everything is a sting
IE: you have no way of telling if http://site.com/api/action?thing=1 did you mean 1 or "1"?
That's why actions have formatters where if you know userID should always be an integer, you can parseInt()it
so arrays are even trickier: many frameworks have opposing views on how to represent arrays
I've seen all of the above:
?data=[1,2,3]
?data=1,2,3
?data="[1,2,3]"
?data=1&data=2&data=3
Since actionhero doesn't know what frontend framework you are using, no we don't do any atomatic array parsing
Evan Tahler @evantahler Aug 13 2015 05:39
make a middleware for it!
Victor Heng @bakavic Aug 13 2015 20:09
hmm, I was more thinking of passing a JSON array as the only input, like:
POST /whatever HTTP/1.1
Host: api.example.com
Content-Type: application/json
[
{
'name': 'Alice',
'age': 15
},
{
'name': 'Bob',
'age': 20
},
...
]
Currently, I can work around it by encapsulating it in a data param.
Just wondering how we could go about solving this without encapsulating the array in an object, while still allowing for:
Input validation of the objects in the array
Support for passing of route params (the uuid in whatever/:uuid)
Middleware could probably massage it into a workable form, but this seems like a common use-case, and I wanted to see how it could be solved for everyone.
Evan Tahler @evantahler Aug 14 2015 00:47
Just have 2 params? One for the route and another for datA?
udomsak @udomsak Aug 14 2015 00:55
Hey guy. i'm just start to using Actionhero and found problem when i test on CircleCI with 2 instance of redis but looklike my ActionHero can't connect redis on CirccleCI. So for local everything is work fine.
Please suggest how to debug or solving this problem ? :)
no idea what happen and how to debug.
Evan Tahler @evantahler Aug 14 2015 02:04
looks like you have to enable redis in your test yml
also, if there are seperate connection settings (not localhost and port 6379), you'll need to get those into the /config/redis.js
you can probably source process.env.REDIS_PORT or something like that
Evan Tahler @evantahler Aug 17 2015 05:07
new version: v11.5.1: Small fixes to the behavior of grunt console
DefunctExodus @DefunctExodus Aug 17 2015 05:17
Still kind of new to actionhero and I am just curious what the best way to setup redundant redis connections is.
Evan Tahler @evantahler Aug 17 2015 05:49
Redid sentiel will let you have the master redis + slaves. The sentinel process will handle master election for you. The node-redis-sentinel package or io redis can be used to connect to sentinels.
DefunctExodus @DefunctExodus Aug 17 2015 06:04
Yep I was looking at sentinel, i am just not sure how to define multiple sentinel endpoints in the actionhero config. Thanks.
Evan Tahler @evantahler Aug 17 2015 12:30
something like this:
exports.production = {
redis: function(api){
return {
channel: 'actionhero',
rpcTimeout: 5000,
package: 'redis-sentinel-client',
failover_reconnect_timeout: 15,
// USE HOST/PORT, pick any host in your sentinel pool
port: 26379,
host: '1.2.3.4',
// OR
sentinels: [
[host1,port1],
[host2,port2],
]
password: 'xxx',
database: 0,
options: {
master_auth_pass: 'xxx',
masterName: 'myCluster',
}
}
}
}
and be sure that you have redis-sentinel-client in your package.json
DefunctExodus @DefunctExodus Aug 17 2015 12:45
Awesome thank you, the sentinel array section was what I could not see in the documentation.
udomsak @udomsak Aug 21 2015 05:00
Hi guy, Can i use Actionhero to control maximum memory reach.
Evan Tahler @evantahler Aug 21 2015 05:09
I... Don't know what that is?
udomsak @udomsak Aug 21 2015 05:12
i want some kind of method like automatic restart actionhero when it use over my memory limit that i define.
PM2 can't start when use with actionhero with startCluster option.
Neil Craig @neilstuartcraig Aug 21 2015 06:02
I’d suggest looking and standard watchdog utilities like monit (https://mmonit.com/monit/) as they are purpose-built for what you want. You can specify what script to run for a restart so that could be something you custom build
Should be simple to do
I guess there is the question of why the process would be using too much memory though…restarting won’t fix the problem, just the symptom. Maybe OK as a stop-gap fix though.
Evan Tahler @evantahler Aug 21 2015 06:40
I've used monit with startCluster hallily
Happily
However, you don't need start cluster if you use pm2. They both spawn
Both spawn children. So if you start a few instances with pm2 it will work more or less the same
There's nothing magic with startCluster. It just keeps a few children alive underneath that are normal actionhero start
udomsak @udomsak Aug 23 2015 19:12
@evantahler , It can cause problem or not because actionhero have cluster function to dealing with sessions and internal routing. So when i ran PM2 front of Actionhero , However the cluster funciton are work well ?
Evan Tahler @evantahler Aug 24 2015 00:32
Should be ok, yep. There is no interprocess communication, it all goes through redis for this reason.
udomsak @udomsak Aug 24 2015 04:00
@evantahler thank you.
:)
udomsak @udomsak Aug 25 2015 03:31
However i found the problem Actionhero not found module -> 'Error: Cannot find module './node_modules/actionhero/bin/methods/generate.js'
My reproduce.
npm install actionhero --save NOT WORK
export actionHero_root NOT WORK
export project_root NOT WORK
export ACTIONHERO_ROOT NOT WORK
remove node_module and reinstall it work on first-time second and next , FAIL ALL
Neil Craig @neilstuartcraig Aug 25 2015 03:51
Hey @udomsak - what’s the error message you’re seeing? Is it the E_ACCESS one from npm?
udomsak @udomsak Aug 25 2015 04:07
@neilstuartcraig no.
how actionhero deal with their module underl ./node_modules/actionhero/bin/methods/*'
Evan Tahler @evantahler Aug 25 2015 04:50
Looks like a permissions or CWD issue to me.
But that's all I can see
How did you install node and npm
udomsak @udomsak Aug 25 2015 05:00
@evantahler no error i remove 'cwd' from pm2 configuration start . it work but have a new error instead.
Evan Tahler @evantahler Aug 25 2015 08:48
perhaps you would be better off asking help in the pm2 issues? https://github.com/Unitech/pm2/issues
DefunctExodus @DefunctExodus Aug 26 2015 11:31
@evantahler With your comments about the start cluster not having anything magic behind the scenes, Is it fair to say that If I wanted to I could run a docker container for each node rather then a container that runs cluster?
salles @sallespro Aug 26 2015 12:39
@DefunctExodus most definitly. i suggest using https://github.com/gliderlabs/docker-alpine to make it minimalistic.
DefunctExodus @DefunctExodus Aug 26 2015 12:42
@sallespro Perfect thank you, I have just been running 2 containers with 10 nodes in each per server. But I hated it lol
Chad Robinson @crrobinson14 Aug 31 2015 13:03
@udomsak We no longer use PM2, but this config worked for us for ActionHero in cluster mode while we did:
This message was deleted
"name" : "API",
"cwd" : "/opt/firetalk/api",
"script" : "/opt/firetalk/api/node_modules/.bin/actionhero",
"args" : "startCluster",
"watch" : false,
"env" : {
"NODE_ENV" : "production",
"ACTIONHERO_CONFIG" : "config,local-config",
"ACTIONHERO_ROOT" : "/opt/firetalk/api/node_modules/actionhero",
"HTTP_PORT": 8080
},
"instances" : "1",
"error_file" : "/var/log/pm2/api.err",
"out_file" : "/var/log/pm2/api.out",
"pid_file" : "/var/log/pm2/api.pid",
"exec_mode" : "fork_mode"
}]
You have to run it from a JSON config file, not raw command-line params.
We switched to forever because, like many others, we've had problems with PM2 using too much CPU for unexplained reasons.
Although I really loved PM2, we just ran out of time sorting out all its issues.
Samuel Marks @SamuelMarks Sep 05 2015 06:27
hi
Evan Tahler @evantahler Sep 05 2015 08:37
Hello
Samuel Marks @SamuelMarks Sep 06 2015 03:05
Hmm, actionhero isn't the right choice as an Express replacement, right? - It's more of a socket.io thing that falls back depending on client's capability?
dunse @dunse Sep 06 2015 04:00
I would say it depends on your user case.. I normally prefer actionhero due to its structure with actions, initializes etc
Samuel Marks @SamuelMarks Sep 06 2015 06:49
Mmm, well immediate use-case is to generate a scaffold from Swagger
So I might just stick to Connect, Express, Hapi and the like (at least for now)
Evan Tahler @evantahler Sep 06 2015 11:39
There is a pretty neat swagger+actionhero plugin: https://www.npmjs.com/package/ah-swagger-plugin
new version released! https://github.com/evantahler/actionhero/releases/tag/v11.6.0
v11.6.0: Package Upgrade
@evantahler evantahler released this 13 minutes ago · 1 commit to master since this release
Upgrade dependent packages
This includes an update of the node-resque package, which now has helpers to allow for running jobs on a schedule (like CRON).
A new section has been added to the actionhero documentation on how to take advantage of this feature @ http://www.actionherojs.com/docs/core/tasks.html#job-schedules
DefunctExodus @DefunctExodus Sep 06 2015 12:03
That is a great update (resque). Thanks
Evan Tahler @evantahler Sep 07 2015 16:23
BUY ACTIONHERO STICKERS https://www.stickermule.com/user/1070682517/stickers
Alexandru Stanciu @alexstanciu Sep 10 2015 01:43
@evantahler is there any way to auth each socket connection before using any verb except ... let's say AUTH? I think I can make an auth action for socket clients and after that based on connection.isAuth I can let them execute other actions. I don't know if this is a good aproach, please advice
Evan Tahler @evantahler Sep 10 2015 07:51
@alexstanciu sure! Make a middleware for all the other actions that requires connection.authd === true or similar, and set that with your auth action.
for socket/websocket connections you might also want to have a task that periodically checks all connections , and kicks out those that haven't set authenticated
Alexandru Stanciu @alexstanciu Sep 10 2015 07:52
ok. good to know. Thanks
DefunctExodus @DefunctExodus Sep 10 2015 17:52
This may be a stupid question but is there anyway to direct a task to the resque "master" server? specifically with regards to running jobs on a schedule with v11.6.0
Evan Tahler @evantahler Sep 10 2015 18:10
There is no master server. That's the point of rescue!
DefunctExodus @DefunctExodus Sep 11 2015 05:18
Sorry poor choice of words, Essentially I am just looking to find the task server (we have multiple) that is in charge of scheduling jobs since there can be only one, I was basing the usage of the word master off "resque_scheduler_master_lock". I am looking to update our scheduled jobs on the fly
Evan Tahler @evantahler Sep 11 2015 07:09
Ahh. Whoever has the lock can change. You should update all servers.
Nick Collins @ndcollins Sep 11 2015 11:51
Out of curiosity, with the news of Node.js 4.0 being released, do any of the breaking changes therein (https://github.com/nodejs/LTS/wiki/Breaking-changes-between-v0.12-and-next-LTS-release) affect ActionHero, and is there an ETA on updating Actionhero to support Node.js 4.0?
Nick Collins @ndcollins Sep 11 2015 12:14
At first blush it doesn’t appear that any of the libraries AH, or my app, is using has any conflicts
Evan Tahler @evantahler Sep 11 2015 12:30
just ran the test suite on 4.0... everything is fine!
there may be something with url.resolve(), but that would be it I think
I can't speak for underlying packages, like the WS transports thougth
Nick Collins @ndcollins Sep 11 2015 12:46
I just spun up a Heroku instance with 4.0. ActionHero started fine, Requeue tasks are running without error, Firebase is connecting without error, MongoDB is connecting without error and is able to find and create records ( using Waterline ORM ), all actions are executing as expected. I’ve not tested the WS or Socket transports but as near as I can tell everything will run without any changes
Evan Tahler @evantahler Sep 11 2015 13:34
Here's the latest Travis.CI build, which I added 4.0 tests too... all green! https://travis-ci.org/evantahler/actionhero/builds/79909088
Evan Tahler @evantahler Sep 11 2015 13:43
@/all If I were to remove the stats initializers into a plugin, would anyone be upset?
Neil Craig @neilstuartcraig Sep 11 2015 13:45
Nope. I think it'd be a better place for it tbh. I don't use it myself.
Nice that AH is v4 compatible too
Evan Tahler @evantahler Sep 11 2015 13:48
exactly. I can't recall seeing that anyone has used it meaningfully, so I wan to clean up the core
omichowdhury @omichowdhury Sep 11 2015 15:22
agreed, we've had it disabled from the beginning
Evan Tahler @evantahler Sep 11 2015 16:30
Cool. Past Evan didn't know what he was doing.
Nick Collins @ndcollins Sep 12 2015 12:07
@evantahler I’m sure it seemed like a good idea at the time :-)
Alexandru Stanciu @alexstanciu Sep 14 2015 02:48
hello guys, anyone knows how to generate "one time" url? I want to protect my api calls, those calls are public but I want to block scrapping. I checked some android apps and it seams they generate a hash before path, eq "www.domain.com/api/HASH/materials/";. The url can't be accesed second time, even if you try from same device ... I tested with fiddler. I also need to implement this for browser. I know this is out of AH scope ... I'm just asking in case someone has an idea.
salles @sallespro Sep 14 2015 07:16
@alexstanciu just create an action that tracks the hash in a persistance db..?
Evan Tahler @evantahler Sep 14 2015 08:37
Yeah, store some hashes in redis with api.cache. Use a wildcard route
Nick Collins @ndcollins Sep 14 2015 09:38
I’m getting an error with AH 11.6.0 where any server errors such as "unknown action or invalid apiVersion” crash the server. According to the stacktrace, it is coming from the web.js line 262 where the property ‘servers’ is undefined on the object api.config.errors.serializers
any idea why this would be?
Evan Tahler @evantahler Sep 14 2015 09:40
There's a new setting in config/errors you might need to bring over
Nick Collins @ndcollins Sep 14 2015 09:45
yep that was it, thanks
Evan Tahler @evantahler Sep 14 2015 11:07
sorry about that, that should have been a more major release as it doesn't merge with defaults properly
:/
Evan Tahler @evantahler Sep 14 2015 13:03
V12.0.0 is up! https://github.com/evantahler/actionhero/releases/tag/v12.0.0
Nick Collins @ndcollins Sep 15 2015 08:06
Kudos on another great release
chimmelb @chimmelb Sep 15 2015 08:26
Writing some tests for WebSockets. If I put the prescribed line eval(api.servers.servers.websocket.compileActionheroClientJS()); in a test file, outside a describe() (but called within before()), things work. When I try to put it in a helper file, I get a Uncaught ReferenceError: ActionheroClient is not defined. I'm trying to automate the creation of clients. Anyone else do testing with WebSockets in this way (multiple client interactions)? Is there a newer way to do things from recent releases?
Evan Tahler @evantahler Sep 15 2015 08:39
Well, to do that you need to be sure the server has booted first
You can also just fs.readfile from public as well
However, I would suggest that you just use the spechelper
I imagine you are trying to test your actions and middleware, not the ws transport itself.
chimmelb @chimmelb Sep 15 2015 08:40
heh, I just read that section now. So to create "clients", instead of actual WebSockets, just use new api.specHelper.connection()
correct, I'm just testing actions and middleware. Thanks for pointing in the right direction : )
Evan Tahler @evantahler Sep 15 2015 08:42
Yup. That's exactly what it's for :)
Because ws-ing to yourself in a test gets a bit crazy.
Chuck out the tests for specHelper itself. They go through most of the use cases. https://github.com/evantahler/actionhero/blob/master/test/core/specHelper.js
Nathan @BoLaMN Sep 15 2015 11:06
Before I start digging through code is there any hooks for attaching to the member left cluster event so I can requeue jobs that the server had been processing
Evan Tahler @evantahler Sep 15 2015 16:43
Well. The actionhero server shouldn't shut down until all tasks it is working are complete. Unless you force kill it...
But I don't think si
Nathan @BoLaMN Sep 16 2015 02:28
I was thinking unexpected server loss and how to fetch them jobs so another server can handle them instead
Evan Tahler @evantahler Sep 16 2015 08:23
Ahh. It's best to look in redis. There's a status hash about what jobs each worker is working on. If the sever dies, you can check what they would have been working on.
Assuming you check that before the old worker is cleared, you can recover the job
DefunctExodus @DefunctExodus Sep 17 2015 06:21
@evantahler Really like the change to ioredis.
Evan Tahler @evantahler Sep 20 2015 20:10
Hey everyone! I'm putting together an Actionhero + Angular + Bootstrap + CORS + CRSF demo. Let me know your thoughts! https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf
and you can play with it: http://angular.actionherojs.com/
Nathan @BoLaMN Sep 21 2015 01:22
@evantahler I'd steer clear from using $rootScope and instead use a factory or a service for your actionHelper and as well as not using $scope and instead use vm = this and controllerAs: 'ctrl' also
Maybe look at using the iffe design pattern to keep it clean.
I too had a similar idea I'm just cleaning up https://cldup.com/83cDgy0Jav.png its a bit purpose focused to opensource it but if I have time I'll universify it and release it currently working on using scheme form with the swagger models to automatically scaffold the application
Evan Tahler @evantahler Sep 21 2015 08:03
@BoLaMN I'm new to angular... can you show me an example of making that factory... or better yet, show me in a pull request? That would be very helpful
Folks keep asking how to do this kind of thing, so I figured it was time to have a "fully baked" example
DefunctExodus @DefunctExodus Sep 21 2015 08:14
I agree 100% with using a service and controllerAs syntax.
Evan Tahler @evantahler Sep 21 2015 12:38
@DefunctExodus cool. Show me how in some pull requests!
DefunctExodus @DefunctExodus Sep 21 2015 12:40
I will once I am back if still needed just at a conf
salles @sallespro Sep 21 2015 12:41
@evantahler fully baked are top.
cool !
Nathan @BoLaMN Sep 22 2015 04:32
@evantahler check my last commit for the old swagger pull request. i had pretty much a fully fledged app working, it wasnt using the controllerAs syntax as it wasnt the norm back then.
had a factory for an actionRunner + chat
DefunctExodus @DefunctExodus Sep 22 2015 05:17
I will do a PR today, hopefully find some time during sessions over the next couple days.
Nathan @BoLaMN Sep 22 2015 05:40
fair enough, was just mentioning that pr as it handled welcome page, stats, chat and swagger utilizing the actionheroClient.js in one bundle so it would of been a decent example.
Nathan @BoLaMN Sep 22 2015 05:47
was thinking about creating an initializer to tie in with waterline and creating some database structures + actions to handle users (token\refresh token), roles and acls and maybe an automatic action\route generator based from models, would anyone be interested in such a thing?
DefunctExodus @DefunctExodus Sep 22 2015 06:49
Personally I would be interested I seeing your take on it. But i don't think I would use it on production since we use ldap & sap acl system.
Nathan @BoLaMN Sep 22 2015 07:01
was thinking about tieing in passport to handle the oauth2 registration\login
i know theres an ldap module for passport not sure about sap thou
saps cluncky anyway hate supporting it at work lol
DefunctExodus @DefunctExodus Sep 22 2015 07:04
Yeah I am using passport and ldap, works very well. The sap portion is what we use to build out acl. Access is given to a position (container) not a person although we using a person to find the position.
Makes Corp moves essentially handle them selfs
Nathan @BoLaMN Sep 22 2015 08:28
hubot intergration ftw :thumbsup:
https://cldup.com/3VVbCLwUG6.png
Nathan @BoLaMN Sep 22 2015 08:35
Extended the robot class to so the hubots now have access to the api object which is pretty sweet
Time to create a plugin package
DefunctExodus @DefunctExodus Sep 22 2015 08:52
That's cool
Nathan @BoLaMN Sep 22 2015 10:32
https://cldup.com/halaxUwLyL.png
localhost:8080/api/hubotSay?msg=hello&channel=random
webhook created!
Neil Craig @neilstuartcraig Sep 22 2015 12:50
Hope I'm not butting in but I just came across nsolid from node source which seems like it'd be great abd easy for profiling. I know @dangerdespain and @evantahler were interested in profiling previously.
https://nodesource.com/products/nsolid
Haven't tried it yet but it looks super nice
Nathan @BoLaMN Sep 22 2015 14:17
not a fan how it takes over /bin/node
Evan Tahler @evantahler Sep 22 2015 21:21
@BoLaMN nice! If it helps, here's a fulll XMPP integration for hipchat https://github.com/evantahler/ah-hipchat-server-plugin
Nathan @BoLaMN Sep 22 2015 23:06
@evantahler https://github.com/BoLaMN/ah-hubot-plugin give it an adapter and it can talk with any server
Evan Tahler @evantahler Sep 23 2015 06:51
Yes!
DefunctExodus @DefunctExodus Sep 23 2015 08:25
I am going to install that into my primary app next week. Nice plugin.
Nathan @BoLaMN Sep 23 2015 16:20
ive added an exception reporter + a @bot verbose on\off for spewing the whole log file out aswell
ill commit that once ive tested it abit more
Nathan @BoLaMN Sep 23 2015 16:29
eg https://cldup.com/6JthqDiIi4.png
Nathan @BoLaMN Sep 23 2015 17:13
@evantahler going to enable tasks to be able to define a logging level are u cool with somethin like that in the main source?
Nathan @BoLaMN Sep 23 2015 17:29
hmm i think logs overall need some love. maybe better namespaced
Evan Tahler @evantahler Sep 23 2015 17:47
all the logic for the task loggers is here https://github.com/evantahler/actionhero/blob/master/initializers/resque.js#L75-L89
lets see what you come up with !
Nathan @BoLaMN Sep 23 2015 17:49
trying to figure out a nice way to decipher all these logs into something nice but nothings really namespaced that well. eg
2015-09-23 16:58:46 - debug: worker: working job Nathans-MacBook-Pro.local workerId=1, class=pollForFiles, queue=Nathans-MacBook-Pro.local
2015-09-23 16:58:46 - debug: re-enqueued recurrent job pollForFiles
maybe i might go thru and make sure everythings namespaced
or even change api.log to be api.log (namespace, msg, severity)
similar to debug
<3's debu
debug*
u can see ioredis using it nicely https://cldup.com/GliyEC2eLw.png
Evan Tahler @evantahler Sep 23 2015 17:52
Element that you can also add custom transports to Winston (via Config) and do things that was
Way
Nathan @BoLaMN Sep 23 2015 17:56
id rather not deal with winstons transport's tbh i dont find them attractive to deal with at all, winston seems to becoming obsolete in my eyes work seems to of come to a halt, 18 outstanding pull requests no code commits for 2 months. :/
Nathan @BoLaMN Sep 23 2015 18:02
I only say this as I pipe the logs into loggly and logs aren't very machine readable is all.
Evan Tahler @evantahler Sep 23 2015 18:28
Fair enough. What's the new Winston?
Nathan @BoLaMN Sep 23 2015 18:29
hmmm not sure
Evan Tahler @evantahler Sep 23 2015 18:29
We can see
we can swap if there is something better
Nathan @BoLaMN Sep 23 2015 18:30
im happy to keep winston maybe the solution is to just name space the logs and define them abit more structured
i can go thru and rename some things
eg
api.log('resque scheduler started', 'info')
Evan Tahler @evantahler Sep 23 2015 18:30
I guess I don't understand what namespace means on a single line. Prefix?
Nathan @BoLaMN Sep 23 2015 18:30
maybe api.log('resque: scheduler started', 'info')
Evan Tahler @evantahler Sep 23 2015 18:31
Ahh, just log line cleanup.
Nathan @BoLaMN Sep 23 2015 18:31
yea
Evan Tahler @evantahler Sep 23 2015 18:31
Sure! Go for it!
Nathan @BoLaMN Sep 23 2015 18:32
'action loaded: ' + action.name + ' @ v' + action.version + ', ' + fullFilePath;
'action: status: loaded: ' + action.name + 'version: ' + action.version + ' path: ' + fullFilePath;
or something like that anyway
so pretty much the log for each file is prefixed with its purpose (eg filename)
cache:
tasks:
redis:
Nathan @BoLaMN Sep 23 2015 18:40
if it was all prefixed we could create a transport for winston easier eg.
splitValue = (value, index) ->
[ value.substring(0, index), value.substring(index + 2) ]
text = 'cache: started job'
[action, message] = splitValue text, text.indexOf ':'
JSON.stringify action: action, message: message
# {"action":"cache","message":"started job"}
Jacob Fike @jacobfike Sep 28 2015 14:45
Is there a way to make redis optional? I don't want my server to crash when redis is down.
Evan Tahler @evantahler Sep 28 2015 17:44
Sure, use the fake-redis gem internally. You will lose any cross-server communication, but if you don't need it, that's the way to go
More interestingly... Why does your redis keep crashing?!
Chad Robinson @crrobinson14 Sep 29 2015 14:48
I agree, Redis dying is a disaster in most environments.
FWIW we use fakeredis for Dev and QA boxes. Works great.
In fact that was a really nice touch in AH to support that. It's easy to add to almost any project, but having support for it basically built-in just saved that pesky little detail. Those side-line items are always the time-sinks in new projects.
Just curious for the group, would anybody be interested in a tech chat about how we built Firetalk? Firetalk is a free, pro-broadcaster-oriented (as opposed to the Periscopes of the world which is focused on consumers) video chat service. We relied heavily on ActionHero when building it and I've thought about doing a half-hour thing talking through how we did it.
Would folks be interested in a Q&A like that?
Evan Tahler @evantahler Sep 29 2015 15:04
I would!
Make sure to record it
DefunctExodus @DefunctExodus Sep 29 2015 15:09
I also would be.
Chad Robinson @crrobinson14 Sep 29 2015 16:41
We record everything, and use the Task subsystem to manage uploading saved episodes to channel owners' YouTube channels. :)
Evan Tahler @evantahler Sep 29 2015 17:52
Boom.
That's the best answer
Nathan @BoLaMN Sep 30 2015 01:14
hmm i have to agree somewhat with @jacobfike i think there needs to be a retry backoff function added for redis
i forget to start redis locally some times and it just spams hard core and then crashes out
Neil Craig @neilstuartcraig Sep 30 2015 01:53
hey @crrobinson14 - i would be and there may be folks here who’d be interested to hear about it too (I work at the BBC) so if you do put something together, i’d really like to hear about it. Is firetalk open source too? i’m getting involved in working towards doing more of our tech work in the open here and i think there’s a lot of appetitte for it nowadays which i’m very keen to promote and nurture where i can
Nathan @BoLaMN Sep 30 2015 02:19
APPIRIO use actionhero nicely, would be interesting to see how they started from the ground up too.
Evan Tahler @evantahler Sep 30 2015 07:15
@BoLaMN ioredis does exponential backoff by default when it can't connect
Nathan @BoLaMN Sep 30 2015 08:47
hmm that is using ioredis.. and a local redis-server
Evan Tahler @evantahler Sep 30 2015 11:35
Very strange. What os, redis version, socket vs port?
Nathan @BoLaMN Sep 30 2015 14:37
Redis 3.0.0 (00000000/0) 64 bit
Running in standalone mode
Port: 6379
2015-10-01 07:07:39 - notice: log: starting actionhero
2015-10-01 07:07:39 - emerg: redis: Redis Error (client): Error: connect ECONNREFUSED
2015-10-01 07:07:39 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
2015-10-01 07:07:39 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
2015-10-01 07:07:39 - emerg: redis: Redis Error (client): Error: connect ECONNREFUSED
2015-10-01 07:07:39 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
meh
halts actionhero from starting till redis is avaliable
2015-10-01 07:08:56 - emerg: redis: Redis Error (client): Error: connect ECONNREFUSED
2015-10-01 07:08:56 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
2015-10-01 07:08:57 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
2015-10-01 07:08:57 - emerg: redis: Redis Error (client): Error: connect ECONNREFUSED
2015-10-01 07:08:57 - emerg: redis: Redis Error (subscriber): Error: connect ECONNREFUSED
Devin Despain @dangerdespain Sep 30 2015 15:03
thanks for the shoutout @neilstuartcraig ! I'm back at the profiling game and none of the existing tools seem to be able to catch what's tying up CPU besides "program" .. I can start up a server just fine and it'll behave but if I even do so much as run a completely stripped-down action, my CPU usage is spiking to 100% and staying there :(
Devin Despain @dangerdespain Sep 30 2015 15:13
http://tinypic.com/r/3494h8w/8
This message was deleted
Evan Tahler @evantahler Sep 30 2015 15:45
@BoLaMN that's the point! You can't boot Actionhero unless redis is ready!
Nathan @BoLaMN Sep 30 2015 15:52
hmm fair enough
Kerim Incedayi @cevatkerim Sep 30 2015 19:50
is there a way to extend the cache expireTime when reading it?
Kerim Incedayi @cevatkerim Sep 30 2015 19:56
I found it. never mind :)
Evan Tahler @evantahler Oct 01 2015 07:51
Yay!
Devin Despain @dangerdespain Oct 01 2015 23:51
Weirdest thing.. I started deleting initializer files trying to isolate our CPU spikes and the issue seems to have disappeared just from deleting/restoring the files. Any ideas on why this might happen? I'm happy to have the problem solved, of course, but my curiosity is now spiking!
Evan Tahler @evantahler Oct 02 2015 01:48
Lol not without seeing your files.
Encoding issues maybe?
But that's really inliklry
*unlikely
Devin Despain @dangerdespain Oct 02 2015 01:49
yeah, seemed strange!
black magic, perhaps :)
Neil Craig @neilstuartcraig Oct 02 2015 04:39
or maybe permissions or damaged disk sectors. probably worth running a disk check if you haven’t nice that it’s sorted
Siddique Ahmad @SiddiqueAhmad Oct 06 2015 02:10
periodic tasks stopped working, could not find any reason, normal task are working okay, any clue
Evan Tahler @evantahler Oct 06 2015 07:20
Is the scheduler enabled? Look in redis. Are there jobs in the delayed queue?
Chad Robinson @crrobinson14 Oct 07 2015 07:35
Hi folks. I'd like to share a summary about an issue we had with ActionHero last night. It wasn't ActionHero's fault but it was a lesson learned about the architecture you may be interested in.
Firetalk heavily relies on ActionHero's chat room services. Last night, in The Young Turks post-game broadcast, we had 1300+ users all chatting together with a lot of join/leave activity. This was a significant growth over the ~300 simultaneous-users-per-room we had been supporting before.
We use AWS for hosting, with RDS for our MySQL database and ElastiCache-Redis for ActionHero's pub/sub and other requirements.
We have a scaling mechanism that allows us to add ActionHero nodes to the stack very rapidly. This works very well. However, high join/leave and chat activity was driving a lot of workload to Redis and MySQL. What we found is that adding Redis and MySQL nodes was occurring MUCH more slowly. We can boot ActionHero nodes with our management tools (Chef, etc.) in about 90 seconds. But adding Redis/RDS nodes was taking 5-10 minutes.
This caused a concentration of workload into those back-end resources - we added API capacity to serve the users successfully, but the API nodes themselves couldn't get their work done. A compounding factor was frustrated users refreshing their browsers to try to "fix" it, which just produced more join/leave activity across the stack.
Chad Robinson @crrobinson14 Oct 07 2015 07:41
We will be altering our architecture such that Redis and MySQL read slaves are actually collocated on the API nodes themselves, not because of a network-traffic concern but because this will allow us to scale the entire API stack horizontally, synchronously (that is, adding API capacity will add everything required for API - ActionHero, Redis, and MySQL). It takes some doing to do this properly with Redis and MySQL but it can be done.
We will probably also split out the chat room services to a separate "stack". It's a little difficult to monitor "inside" ActionHero to see where workload is going - you can see how hard NodeJS is working, but not how much is going to each component (chat room, API calls, etc.) We're 99% confident live-chat was the piece that was struggling, but splitting it out will let us confirm that and manage it as its own "thing".
Finally, we will be disabling room-status messages in our app. Clients/browsers just can't keep up with active join/leave activity in a 1300-viewer room. It's not really valuable to send that data to them anyway because nobody wants to scroll through 1300 avatars/names to see if a buddy is in the room with them, especially if the list is actively being updated.
Greg Coonrod @gcoonrod Oct 07 2015 07:59
@crrobinson14 Thanks for sharing! Those are some interesting things to think about. I'd really like to hear about how you include the Redis read slaves in your api components.
@evantahler Do I have access to any information about the node-resque worker in my AH tasks? I'm trying to improve the logging going on in our production AH components and it would be nice to be able to tag all log entries with the worker ID.
Chad Robinson @crrobinson14 Oct 07 2015 10:15
@gcoonrod It's not necessarily a public API, but node-resque is attached to api.resque and you can see in node_modules/actionhero/initializers/tasks.js how AH itself talks to it (like in workers()).
api.resque.queue is the actual node-resque connection if you need to poke around the internals to get information about the connection
About Redis, we use DataDog as one of our main infrastructure monitors. Here's a chart of our Redis workload for chat room activity last night.
Chad Robinson @crrobinson14 Oct 07 2015 10:21
https://www.dropbox.com/s/rrgziavoufnfsbh/redis-spike.png?dl=0
That's a lot of data moving through - I don't have great monitors on the breakdown between room join and chat workload, but on instinct we think it was about 60% join/leave activity re-generating room status messages (viewer lists) and 40% chat.
Greg Coonrod @gcoonrod Oct 07 2015 10:23
Thats crazy
Greg Coonrod @gcoonrod Oct 07 2015 10:47
Using the AH REPL is there an easy way to determine if the node that you're connected to is running a task processor?
Evan Tahler @evantahler Oct 07 2015 17:44
REPl is its own node, and it won't run a task processor.
@crrobinson14 first, awesome work that you had that many users!
Hit me up private and I can share some autoscaling strategies.
You you should also publish that retro to the mailing list so it is a little more per many.
Permanent.
New versions of Actionhero dropped the room join/leave messages brw
Btw
For exactly that reason.
Evan Tahler @evantahler Oct 07 2015 18:10
Thinking about this more, 2k users should be fine on one redis instance... We do that as TaskRabbit all the time
One Actionhero instance on a medium server should handle that fine.
Then again you may have all sorts middleware going on
Greg Coonrod @gcoonrod Oct 07 2015 21:00
My task workers always have undefined in their name and I'm having a hard time figuring out where that is coming from. Could someone enlighten me?
Evan Tahler @evantahler Oct 07 2015 22:20
where do you see this name? redis? logs?
Greg Coonrod @gcoonrod Oct 08 2015 06:17
In redis, I see workers named undefined:10023+1
Greg Coonrod @gcoonrod Oct 08 2015 07:04
Some visual reference.
Evan Tahler @evantahler Oct 08 2015 07:31
If you aren't setting custom names, that means that the server can't figure out its own ip address
hostname
https://github.com/taskrabbit/node-resque/blob/master/lib/worker.js
Fascinating! You can confirm with os.hostname
Can you open an issue in the node resque project about this?
Greg Coonrod @gcoonrod Oct 08 2015 07:45
a bit more clarification
This message was deleted
LockingMultiWorker.prototype.startWorker = function(callback) {
var self = this;
var id = (self.workers.length + 1);
var worker = new LockingWorker({
connection: self.options.connection,
queues: self.options.queues,
timeout: self.options.timeout,
name: self.options.name + ":" + process.pid + '+' + id
}, self.jobs, function() {
worker.workerCleanup();
worker.start();
process.nextTick(callback);
});
We've had to override some of the base multiWorker functions.
startWorker in particular. In this case most of the code in the function is exactly as it was in the version of node-resque used by AH v 10.1
what i'm trying to track down is where self.options.name would normally get set.
Evan Tahler @evantahler Oct 08 2015 07:59
Check the defaults in the link above. In your custom prototype, do you source the regular workers defaults?
You could also use api.name within actionhero
Greg Coonrod @gcoonrod Oct 08 2015 10:36
For closure, using os.hostname() in our modified worker was the right approach.
Greg Coonrod @gcoonrod Oct 08 2015 11:10
Out of curiosity. Why do the workers in the resque:workers set in Redis have the queues their worked appended to their name?
e.g. hostname:1008+1:queue1,queue2
Kerim Incedayi @cevatkerim Oct 08 2015 12:39
Can the actionhero client be used in a cli based node app?
Kerim Incedayi @cevatkerim Oct 08 2015 12:56
nevermind I found it..
Evan Tahler @evantahler Oct 08 2015 15:44
@gcoonrod not really sure, that's just how resque has been for years
I assume it's for "connivance"?
@cevatkerim I guess so... what are you trying to do?
Greg Coonrod @gcoonrod Oct 08 2015 15:48
@evantahler off topic but I love your typos
Evan Tahler @evantahler Oct 08 2015 16:48
It's my nom-de-plume
It's the @evantahler seal of quality
Kerim Incedayi @cevatkerim Oct 08 2015 18:12
@evantahler I'm build a cli based admin client
Evan Tahler @evantahler Oct 08 2015 19:19
Cool. Check out grunt console.
Greg Coonrod @gcoonrod Oct 08 2015 19:52
So, connivance or not, having the queues append to the worker name is rather problematic when you have 100+ queues and your queue names are all uuids.
Kerim Incedayi @cevatkerim Oct 08 2015 21:25
is this still valid? https://gist.github.com/juancgarcia/e4caf5dc7474769f5137
Evan Tahler @evantahler Oct 08 2015 22:55
No idea. Is @juancgarcia here?
Giving it a quick look, it seems ok
Kerim Incedayi @cevatkerim Oct 08 2015 22:59
I got login to work but auth fails
Evan Tahler @evantahler Oct 08 2015 23:01
keep at it, and post an update when you solve it!
Kerim Incedayi @cevatkerim Oct 08 2015 23:05
yeah.. I'm about to give up. :worried:
Evan Tahler @evantahler Oct 09 2015 07:27
There are some othe folks hrere like @neilstuartcraig who have used passport
Evan Tahler @evantahler Oct 12 2015 13:51
version release!
https://github.com/evantahler/actionhero/releases/tag/v12.1.0
Allow folks to optionally enable GZIP/Deflate compression for actionhero/servers/web. This can now be toggled on/off with api.config.servers.web.compress. While this option exists, it is still best-practice to have an upstream process handle compression rather than node, like Nginx or a load balancer.
When enabled, if the client indicates they can handle compressed responses (via the Content-Encoding header, we support gzip and deflate), Actionhero will compress results before sending the data over http. This decrease the network payload at the expense of both server and client CPU time.
By @evantahler via #689
Chad Robinson @crrobinson14 Oct 14 2015 16:23
Cool, thanks @evantahler
Anybody have a need to send a message to a given connection no matter where they are in the cluster?
Evan Tahler @evantahler Oct 14 2015 17:10
There is support for that already!
Kerim Incedayi @cevatkerim Oct 14 2015 19:06
Hey @evantahler is there a way to know what worker is running? I see "info: worker: started workerId=2" and the ended but none of the api.log statements in the tasks are showing up. So I have no idea what worker is that one...
Chad Robinson @crrobinson14 Oct 14 2015 19:08
@evantahler How? I know about sending to a connection on the same node, but haven't found an API method for sending to a connection on another node. Especially since api.connections.connections is only a list of a node's local connections.
BTW I've been tracking down stuck task workers (yes, clean shutdown is ideal but nodes and servers CAN crash, and jobLock has a very slow default timeout. I've noticed that the AH docs refer to pluginOptions as an array in code but a "hash" in doc text. I tracked down the code here and confirmed that it is indeed expected to be a hash as it's read in node-resque/lib/pluginRunner.js: var pluginOptions = self.jobs[func]['pluginOptions'][pluginName]
Evan Tahler @evantahler Oct 15 2015 07:45
Re: talking to connections on other servers: http://www.actionherojs.com/docs/core/actionCluster.html#apiconnectionsapplyconnectionid-method-args-callback
so you would do something like
api.connections.apply('connectionIdABC123', 'sendMessage', {message: payload}, function(err){
// error handler
}
what that does is then broadcast out to redis "anyone have this connection? If so call this method on it with these args"
@crrobinson14 can you point out what page in the docs have that wrong? I'll fix it!
or... you know... PR please!
Chad Robinson @crrobinson14 Oct 15 2015 11:10
I don't mind sending a PR, but it's just the bits that illustrate pluginOptions, they do things like pluginOptions: [] with no examples, but the way I'm reading this code, it should be something like pluginOptions: { jobLock: { lock_timeout: 30 } }
Also, it may be worth noting in the docs that the node-resque plugins all appear to take their values in seconds, but actionhero tasks are done in milliseconds.
This message was deleted
This message was deleted
task = {
name: 'storePhotos',
description: 'Move photos and variants from UploadCare to S3/CloudFront for permanent storage.',
queue: 'default',
plugins: [],
pluginOptions: {
jobLock: {
lock_timeout: 30
}
},
frequency: 120000
}
Here's one that seems to be working well for us now. It's a periodic file-mover that can run long, like 5-10s per run. That's long enough that sometimes we catch it if we're practicing bouncing a node in our disaster-recovery testing, for example, and the task then gets "stuck" for a long time, like an hour.
The docs say pluginOptions is a "hash" but shows it as pluginOptions: [] (an array)
Chad Robinson @crrobinson14 Oct 15 2015 11:20
I figured I'd run it by you before sending a PR in case we're misunderstanding something... although the above is working well for us
Kerim Incedayi @cevatkerim Oct 15 2015 11:40
Anyone know how to identify these:
2015-10-15 13:35:05 - info: worker: started workerId=2
2015-10-15 13:35:05 - info: worker: ended workerId=2
2015-10-15 13:36:15 - info: worker: started workerId=2
2015-10-15 13:36:15 - info: worker: ended workerId=2
Chad Robinson @crrobinson14 Oct 15 2015 12:43
Identify...?
Nathan @BoLaMN Oct 15 2015 16:49
Anyone else throw node-inspector on actionhero? Been getting issues lately with memory leaks yet everything is task based.
Chad Robinson @crrobinson14 Oct 15 2015 17:01
We tried once but had trouble with it in a multi-worker, multi-server cluster.
Evan Tahler @evantahler Oct 15 2015 17:03
sure, I've used it. Not in cluster though
Chad Robinson @crrobinson14 Oct 15 2015 17:05
Honestly, our memory leaks are just a nuisance. These AWS boxes have so much RAM even poorly-written code can barely burn through 2-3% of it between deployments. We're continuous-deployment, so even when we're sloppy memory leaks are a small part of what we focus on.
We're restarting all the time.
Chad Robinson @crrobinson14 Oct 15 2015 17:17
[root@api3 ~]# free -h
total used free shared buffers cached
Mem: 31G 5.2G 26G 5.8M 280M 1.2G
That's one node from a 4-node cluster that served a several-hundred-user broadcast for the past few hours.
As you can see, peak memory usage here we're talking 5.2G of which MAYBE on our sloppiest day 100MB is "leaks". We have 26G free. We spend 0 time on this issue. YMMV.
Evan Tahler @evantahler Oct 15 2015 19:20
That's still pretty bad. I've got an actionhero chat server that's been running for weeks (no reboots) and has a few hinder connections at once... 100mb
100*
I wonder if your DB drivers have a memory leak
What redis package? Have you tried ioredis?
Chad Robinson @crrobinson14 Oct 16 2015 05:45
No, we haven't, but I definitely will. And yes, it totally could be our DB drivers. But my point was memory leaks are far less dangerous in these contexts than other types of issues. And we haven't even said it's a LEAK. That 100MB growth over time could be a mix of things, only some of which could be leaks. Remember, the above is coming from "free". It could just be the JSVM has internally had memory released to it, but it hasn't released it to the OS because it "pools" memory pages for future allocations.
But 100MB growth in a 26GB swimming pool? We spend 0 time on this. Our main focus is on performance.
Evan, earlier you mentioned a way to directly message a connection regardless of the node it's on. It seems you're referencing api.connections.apply() to do this but from reading the docs it's unclear to me how this would be used. Are you suggesting remote-eval'ing another API call to send that connection a message?
It's such a useful concept to be able to do (send connection 'X' "this message", no matter where that connection is) that we just made an initializer that goes off a common redis pub/sub topic that all our workers listen to. Would this be a good thing to have in ActionHero core?
I could make a PR for it, although we're still on 11.2.2 - suppose it's time to upgrade. :D
Chad Robinson @crrobinson14 Oct 16 2015 07:56
sendToConnection = function(connectionId, message) {
api.connections.apply('sendMessage', [message], function(err) {
api.log('Error sending cross-cluster message', 'error', err);
});
}
Does this look about righr?
Evan Tahler @evantahler Oct 16 2015 08:16
Close. I'm pretty sure you need to pass the connection id in there somewhere. I'll try it out in a few hours.
Evan Tahler @evantahler Oct 16 2015 11:09
@crrobinson14 bad news: there was a bug
good news: I fixed it: evantahler/actionhero@38a283b
so all you need to do:
var connectionId = '6695ee6d-a5e5-4451-b354-d6a336096500';
var message = {message: 'hello'};
api.connections.apply(connectionId, 'sendMessage', message);
that's it!
There's a new test locking this behavior in
Evan Tahler @evantahler Oct 16 2015 11:27
New version up!
https://github.com/evantahler/actionhero/releases/tag/v12.1.1
Fixed a bug where using the RPC api.connections.apply would fail.
by @evantahler via 38a283b
Updated all dependent packages to their latest versions.
by @evantahler via f6474f9
Chad Robinson @crrobinson14 Oct 16 2015 13:44
Wow, fast work @evantahler Thanks!
Evan Tahler @evantahler Oct 17 2015 14:45
Btw this is really easy to test locally.
Be sure you are using real redis and start a server with npm start in the normal way
Start a console with grunt console
You know that no connections will be local to the console so you can send messages from there and watch them appear on your clients connected to the server in the normal way
Evan Tahler @evantahler Oct 18 2015 09:25
There is currently a large bug with the fakeredis package which prevents it from working. FYI
hdachev/fakeredis#31
Evan Tahler @evantahler Oct 18 2015 10:38
And fixed!
https://github.com/evantahler/actionhero/releases/tag/v12.1.2
Chad Robinson @crrobinson14 Oct 20 2015 03:59
This is what makes Open Source so amazing
Nathan @BoLaMN Oct 20 2015 17:18
@evantahler is there missing documentation regarding tasks? im not sure if im supposed to be defining job.class as i can see a weird redis entry surrounding it https://cldup.com/kj-Hxjg2JE.png
or is this expected?
Evan Tahler @evantahler Oct 20 2015 18:15
nope
here's an example https://github.com/evantahler/actionhero-tutorial/blob/master/tasks/stats.js
Nathan @BoLaMN Oct 20 2015 18:24
hmm looks the same
task stops requeing its self after a long running time so trying to track down possible causes
Kerim Incedayi @cevatkerim Oct 22 2015 19:10
This might be a stupid question but is there a way to restart the actionhero programatically
josephwlh @josephwlh Oct 23 2015 01:50
actionhero can match this type routes ? ^\/([a-zA-Z0-9_.~-]+)\/(.*) => curl localhost:8080/foo/my/cats/name/is/gandalf
Dan @SDSWanderer Oct 23 2015 06:28
hi! I trying to get client ip address, api.connection is a function that throws an error when I call it. Please help
Ok, got it. Never mind
Evan Tahler @evantahler Oct 23 2015 14:17
@cevatkerim http://www.actionherojs.com/docs/ops/running-actionhero.html#programatic-use-of-actionhero
@josephwlh yep, regexp routes are OK http://www.actionherojs.com/docs/servers/web.html#routes
@SDSWanderer cool!
josephwlh @josephwlh Oct 23 2015 18:32
@evantahler but, I try get:[{path:"/:path(^\/([a-zA-Z0-9_.~-]+)\/(.*))", action:"root"] , response "error": "unknown action or invalid apiVersion"
josephwlh @josephwlh Oct 23 2015 18:48
@evantahler in my project, I need a function to respond to all url
Chad Robinson @crrobinson14 Oct 26 2015 09:29
@josephwlh Don't forget AH binds to a sub-path, like /api/XYZ...AH is really best used for its core mission: making an API server. If you want complex routing rules on top of that, Varnish or Nginx in front of it would do better.
We use both, FWIW
Evan Tahler @evantahler Oct 26 2015 22:07
you can remove or change the /api route "base" in the config
check the config options api.config.servers.web.urlPathForActions && api.config.servers.web. rootEndpointType
Evan Tahler @evantahler Oct 26 2015 22:14
@josephwlh you have to remember that / would not be a valid char to match a route with, meaning that if you want to define a route for all possible / "depths", you need to actually define them
IE, this would be a valid config to catch all routes with 0 up to 4 route segments:
exports.default = {
routes: function(api){
return {
all: [
{ path: '/', action: 'status' },
{ path: '/:a', action: 'status' },
{ path: '/:a/:b', action: 'status' },
{ path: '/:a/:b/:c', action: 'status' },
{ path: '/:a/:b/:c/:d', action: 'status' },
]
};
}
};
meaning curl -v localhost:8080/api/a/b/c/d is OK but curl -v localhost:8080/api/a/b/c/d/e is not
Angelo Rodrigues @AngeloR Oct 27 2015 06:14
I know actionhero manages its own startup.. but is there a way/reason to integrate it with pm2?
or should I be leaving it as is and using startCluster instead?
Evan Tahler @evantahler Oct 27 2015 07:14
I use monit, other folks use forever or pm2. Depends on your infrastructure really. How do you want to start the cluster the first time? How do you want to signal an application deploy?
Krishna Glick @krishnaglick Oct 27 2015 07:54
Is there a git repo for actionhero's documentation?
Krishna Glick @krishnaglick Oct 27 2015 07:59
Ah, found it. https://github.com/evantahler/actionhero/tree/gh-pages
Evan Tahler @evantahler Oct 27 2015 08:21
The docs folder in master is the uncompiled version
And we build that branch on publish
Also on the web
Angelo Rodrigues @AngeloR Oct 27 2015 12:13
@evantahler we use pm2 so that each application can configure its own needs: IE, instances, services, etc. I didn't see any functionality like that through actionhero docs
Evan Tahler @evantahler Oct 27 2015 13:08
Nope. Just how many children are running.
Eduardo Gonzalez @eduardogch Oct 27 2015 15:00
Hey guys and Evan, just want to say hi and thanks for this wonderful multiserver
Evan Tahler @evantahler Oct 27 2015 18:07
Yay!
What are you using it for?
Eduardo Gonzalez @eduardogch Oct 27 2015 19:43
I would like to used for a TCP Socket Server but is just amazing how you can send info to web and to be consume in a REST WS
I'm using the latest version but my DB is mongodb and the plugin to conect with mongo doesn't work for me
So I create a plugin who in my humble opinion works better is more simple
Please feel free to check, review and use from here
https://github.com/eduardogch/ah-mongodb-plugin
Dan @SDSWanderer Oct 28 2015 03:51
Hi @evantahler ! I really confused with implementation of cache.checkLock() method. It seems like it never worked correctly! It's not using redis atomic operations like incr(), and my tests shows that is a real problem.
Evan Tahler @evantahler Oct 28 2015 07:33
@eduardogch cool!
I'll add it to the website
@SDSWanderer can you open an issue on github with any problems you are seeing?
test cases always help
Dan @SDSWanderer Oct 28 2015 07:37
Sure, but I will do it in couple of days, too busy right now
Evan Tahler @evantahler Oct 28 2015 07:41
giving it a once-over, it seems to be ok. redis is single threaded, setnx won't collide with an existing lock, and the payload content would be the api server's name. Keep in mind the lock is to an instance of actionhero, not a server or a request
Evan Tahler @evantahler Oct 28 2015 09:19
Gitter now has the ability to embed chat rooms.
we now have a chat button on actionherojs.com !
swanky.
peterkingsbury @peterkingsbury Oct 28 2015 10:01
well this is cool :D
Evan Tahler @evantahler Oct 28 2015 11:23
I know, right?!
Dan @SDSWanderer Oct 28 2015 16:40
@evantahler , please take a look at evantahler/actionhero#695
Thanks!
Evan Tahler @evantahler Oct 28 2015 17:15
Any other folks comfortable with redis, please weigh in evantahler/actionhero#695
Chris Capobianco @ccapo Oct 28 2015 21:18
I concur @peterkingsbury, when could we expect this to become standard in actionhero? ;)
Evan Tahler @evantahler Oct 28 2015 22:03
I think gitter may actually use Actionhero...
Angelo Rodrigues @AngeloR Oct 29 2015 06:31
is there a mechanism for adding additional transports to action error handling? or even to disable the default handling mechanism and utilize our own system?
I’m investigating using actionhero within our company, and we try and keep application generated logs centralized.
Eduardo Gonzalez @eduardogch Oct 29 2015 06:54
Hey guys, I haven been really focus working in create other plugin for RethinkDB for actionhero.js
A great NoSQL database, much better in joins, clustering and production than MongoDB
So please be free to use, review and pull request in the plugin for RethinkDB
https://github.com/eduardogch/ah-rethinkdb-plugin
DefunctExodus @DefunctExodus Oct 29 2015 07:56
@eduardogch very cool thank you
Evan Tahler @evantahler Oct 29 2015 10:28
@eduardogch Neat! added evantahler/actionhero@91cbdb7
@AngeloR I think I understand one of your 2 questions. For logs, we use "winston" which allows you to create all sorts of custom log transports (traps, POSTs, syslog, etc) => https://github.com/winstonjs/winston/blob/master/docs/transports.md
You can see that by default, actionhero just uses 2: stdio and file (https://github.com/evantahler/actionhero/blob/master/config/logger.js)
I don't think I understand what you mean by 'custom error handling' though
each server responds to the client with any errors in a way that makes sense for that server
do you want, for example, every HTTP request to get a 200-OK even though something went wrong?
Angelo Rodrigues @AngeloR Oct 29 2015 10:44
@evantahler Internally we have our own logger module built on top of winston, so I suppose we could just alter config/logger to use ours.
Evan Tahler @evantahler Oct 29 2015 11:02
perfect
Evan Tahler @evantahler Oct 30 2015 13:35
New version up!
https://github.com/evantahler/actionhero/releases/tag/v12.2.0
Support for if-modified-since headers when serving static files
Allows browsers to check if the static file has changed since they last requested it, and actionhero will now respond with the proper 304 header if there is no change. Save bandwidth!
By @lorenzofox3 via #691
Misc
Load configChanges early so that if you are overriding plugin directories, it will take (7a082ee)
Update dependent packages (752f822)
Alexandru Stanciu @alexstanciu Nov 02 2015 00:05
in background task processors are new forks of some other cpu core, different from main one? I'm using actionhero to do some web scrapping of multiple websites using multiple alias ips on my server. Each http request / diff ip. I'm searching a way to spread the cpu usage to all cores
Evan Tahler @evantahler Nov 02 2015 13:08
No, they work in the same process.
Get more servers, and distribute the jobs via redis
Alexandru Stanciu @alexstanciu Nov 02 2015 13:11
@evantahler I can't use multi core processors?
I know by running ah in startCluster is using multi core processor - I think it does this. But I need master-worker communication
Evan Tahler @evantahler Nov 02 2015 13:58
oh, sure
I thought you wanted each request to come from a new IP address
if your tasks are I/O bound (not CPU bound) you can probably have more than one cluster worker per core
and you don't really need any communication at all
as long as you enqueue all your jobs
and ensure that each actionhero server has only 1 worker
each will work 1 job at a time
Alexandru Stanciu @alexstanciu Nov 02 2015 14:07
I want 1 request / ip. The way I'm doing this now is with master <-> fork communication. I have several jobs(not AH) that run with setInterval in master and before I send data to workers I have some logic to bind url to fetch and ip to use. Like this I'm spreading work across multiple cores and I have a "manager" for what ip to use, also I'm receiving message back from forks in order to store them ... not to open X-forks database connections. I basically wanted to implement this in AH for stats and other already made things.
anyways, thanks a lot @evantahler
Kerim Incedayi @cevatkerim Nov 03 2015 10:48
what is the suggested way of upgrading actionhero?
Evan Tahler @evantahler Nov 03 2015 11:28
Minor versions? Just bump it up in the package.json.
Major versions (like > 2.0 delta). Make a new project and copy in your actions and tasks.
Kerim Incedayi @cevatkerim Nov 03 2015 14:01
@evantahler yeah, I was upgrading from 11.
Kerim Incedayi @cevatkerim Nov 03 2015 18:39
is there a way to bypass blockedConnectionTypes when in testing mode?
Kerim Incedayi @cevatkerim Nov 03 2015 21:02
nevermind I figured it out :smile:
Kerim Incedayi @cevatkerim Nov 04 2015 13:33
is there a reason why the validator function fail when using specHelper.runAction?
Kerim Incedayi @cevatkerim Nov 04 2015 13:40
it works fine when I run the server and make requests against it but fails during the tests when I use the specHelper
Kerim Incedayi @cevatkerim Nov 04 2015 13:47
I guess it's a string issue. When I send the request it lands as a string but when I use the spec helper it sends it as a number
Evan Tahler @evantahler Nov 04 2015 15:26
Yep, all HTTP requests are strings all the time (that's how the web works!). It's common to do some type coercion first with a formatter: https://github.com/evantahler/actionhero/blob/master/actions/cacheTest.js#L25-L33
Kerim Incedayi @cevatkerim Nov 04 2015 15:26
thanks!
Evan Tahler @evantahler Nov 04 2015 15:27
feel free to use a helper lib like http://www.typecastjs.org/
Devin Despain @dangerdespain Nov 05 2015 18:02
everyone who uses (or hates) Promise libraries - check out this core mod that attaches a promise chain to an action if a "thenable" is detected.
let me know if this is useful, or just plain crazy
api.actionProcessor.prototype.runAction = function(){
var self = this;
self.preProcessAction(function(error){
self.reduceParams();
self.validateParams();
if(error){
self.completeAction(error);
}else if(self.missingParams.length > 0){
self.completeAction('missing_params');
}else if(self.validatorErrors.length > 0){
self.completeAction('validator_errors');
}else if(self.toProcess === true && !error){
var runFunc = self.actionTemplate.run(api, self, function(error){
if(error){
self.completeAction(error);
}else{
self.postProcessAction(function(error){
self.completeAction(error);
});
}
});
if(runFunc && typeof runFunc.then === 'function'){
runFunc.then(function(res){
self.response.result = res
self.postProcessAction(function(error){
self.completeAction(error);
});
}).catch(function(error){
self.completeAction(error);
})
}
}else{
self.completeAction();
}
});
}
it assumes that a promise is returned from the action.run function and also assumes that done() isn't called in the action
Evan Tahler @evantahler Nov 05 2015 18:31
I'll not weigh in here about my feelings on promises, but rather than monkeypatching api.actionProcessor.prototype.runAction, why not make a middleware with a very low prioirty to handle respolving the promise?
Kerim Incedayi @cevatkerim Nov 05 2015 18:32
Evan Tahler @evantahler Nov 05 2015 18:33
you are also ignoring all post-processor middleware if you don't have a promise (postProcessAction)
Devin Despain @dangerdespain Nov 05 2015 18:33
is there a good way to do promise detection without running the run function?
Evan Tahler @evantahler Nov 05 2015 18:34
hmm
probably not
because you need to know the result of run() to know if it has a then or not
Devin Despain @dangerdespain Nov 05 2015 18:34
that's what resulted in the monkeypatching haha.. couldn't find out until it was actually called
Evan Tahler @evantahler Nov 05 2015 18:34
I get it now
huh
to be 'correct' about this, you would also need to handle middleware and tasks the same way
they could all return prommises I guess
Devin Despain @dangerdespain Nov 05 2015 18:35
that's a good point
Evan Tahler @evantahler Nov 05 2015 18:35
but why wouldn't you resolve your promise within your action?
totally get using prommises within actions
Devin Despain @dangerdespain Nov 05 2015 18:35
it's not very DRY
Evan Tahler @evantahler Nov 05 2015 18:35
like... I do it all the time with sequelize
Devin Despain @dangerdespain Nov 05 2015 18:36
I'm using the same five lines of response/error handling code on every single action
Evan Tahler @evantahler Nov 05 2015 18:36
have an exmple
?
Devin Despain @dangerdespain Nov 05 2015 18:37
run: function (api, data, next) {
var params = {
id : data.params.id,
}
api.models.content.find({
where: params,
}).then(function (result) {
data.response.result = result
next()
}).catch(function (err) {
next(err)
})
}
Evan Tahler @evantahler Nov 05 2015 18:37
I'm used to stuff like this (where all model methods are promoses) https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf/blob/master/actions/user.js
Devin Despain @dangerdespain Nov 05 2015 18:37
yeah, Sequelize made me a convert
Evan Tahler @evantahler Nov 05 2015 18:38
.... thinking ....
Devin Despain @dangerdespain Nov 05 2015 18:38
run: function (api, data, next) {
var params = {
id : data.params.id,
}
return api.models.content.find({
where: params,
})
}
would be the reduction
Evan Tahler @evantahler Nov 05 2015 18:40
makes sense
I think I would be OK with a change like getting into code
*core
as long as you do it for everything (actions, tasks, initializers, etc)
Devin Despain @dangerdespain Nov 05 2015 18:42
probably wouldn't be too tough to spread the love around
Evan Tahler @evantahler Nov 05 2015 18:42
I'm curious though how you can get away with homogeneous 'catch' logic
do you never want to have a custom reponse message when something goes wrong?
I'd rather return 'email address already exists' than 'dupliate key on users.email'
etc
Devin Despain @dangerdespain Nov 05 2015 18:43
I've been working on integrating Sequelize error catching postProcessor middleware
Evan Tahler @evantahler Nov 05 2015 18:44
well then!
Devin Despain @dangerdespain Nov 05 2015 18:44
and yeah, custom error logic would be super handy
I wonder if a new type of middlewares could be added called "onError/onException" or something
it'd kind of be cool to leverage the global/action-specific properties of the middleware layer
Evan Tahler @evantahler Nov 05 2015 18:45
I think I'm a believer that auto-promise resolution makes sense for the 'happy path', but error logic seems to really want to be within the action
could be
I'm skeptical... but hopeful!
I've really never been a position where all functions are promises either
there's always one callback in the bunch that breaks the promise chain and forces me to error handle in the action
like this example: https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf/blob/master/actions/user.js#L51-L84
user.updatePassword is not a promise... so I have to resolve.
Devin Despain @dangerdespain Nov 05 2015 18:52
we've got handfuls of calls that are just straight-up basic sequelize promises
built correctly, a developer not using promises wouldn't even notice the change
Evan Tahler @evantahler Nov 05 2015 18:53
... assumign you never have to break the chain and resolve mid-action
and you promise-ify everything
Devin Despain @dangerdespain Nov 05 2015 18:56
I'm more familiar with Bluebird than I am the other libraries
Evan Tahler @evantahler Nov 05 2015 18:56
pretty sure that the problem remains.
if you have to resolve at any point in your action, the 'return' will happen before you have the second promise created... and then your monkeypatch wont work
Devin Despain @dangerdespain Nov 05 2015 18:57
then chains that can be broken mid action should be returned as a promise
Evan Tahler @evantahler Nov 05 2015 18:58
but you can't return them sync, because you ahve to resolve them
Devin Despain @dangerdespain Nov 05 2015 18:58
or wrapped inside a promise resolver return new Promise(function(resolve, reject){})
Evan Tahler @evantahler Nov 05 2015 18:58
that would work
you just need to do that for... everything
Devin Despain @dangerdespain Nov 05 2015 18:58
naw
your previous code should still work!
since the promise itself isn't being returned
api.models.content.find({
vs
return api.models.content.find({
if a next() callback is used anywhere in the action then it shouldn't be returned as a promise
Evan Tahler @evantahler Nov 05 2015 19:00
as long as you promise-ify everything, yetp
yeah
that's the big footnote :D
Devin Despain @dangerdespain Nov 05 2015 19:01
buyer beware ;)
for now.. I think I might like this better as a plugin than a core change
I'll dogfood it for a bit
Evan Tahler @evantahler Nov 05 2015 19:02
coolio
keep us posted!
Devin Despain @dangerdespain Nov 05 2015 19:02
https://github.com/dangerdespain/ah-promises-plugin
keep an eye out!
RENARD Laurent @lorenzofox3 Nov 06 2015 01:22
For information we wrap all the "run" prop of our action in a "promise factory"
var P = require('bluebird')
module.exports = function actionFactory (fn) {
return function action (api, data, next) {
P.try(function () {
return fn(api, data, next)
}).catch(function exceptionCallback (err) {
// unexpected error (500)
if ((err && !err.statusCode) || !err) {
// log stack of unexpected error
api.log('Uncaught ActionError' + err, 'error')
api.log(err.stack, 'error')
if (process.env.NODE_ENV === 'production') {
data.error = new Error('Internal server error')
} else {
data.error = err || new Error('unknown error')
}
} else {
data.error = err || new Error('unknown error')
}
}).finally(function nextFunc () {
next(null, true)
})
}
}
which is used
var handle = require('actionFactory')
var error = require('./lib/errors')
exports.getProduct = {
name: 'getProduct',
description: 'get details for a particular product',
run: handle(function (api, data, next) {
var q = api.query()
.where('id', data.params.id)
.build()
return api.models.product.find(q)
.tap(product =>{
if(product === null){
error.NotFound('could not find the product') // => will result in 404
}
if(evil === true){
throw new Error('Oups whatever internal server error') // => will result in 500 (wi
}
} )
.then(f.set(data, 'response'))
})
}
And then we have a post processor which handles errors depending on the "httpErrorCode" property present on the error forwarded
the main advantage is to handle action error globally and also to be able to throw application wise errors from the action
RENARD Laurent @lorenzofox3 Nov 06 2015 01:33
And actually the .then(f.set(data, 'response')) (which is some code to set the result to the response) could be mutualise in the actionFactory as well
ie whatever return the promisified action would be the result to send to the client
Devin Despain @dangerdespain Nov 06 2015 02:22
sweet! that's a cool approach - good to see that promises are being used in practice
that's slick how you're naming your promise chain functions, too
didn't know you could do that
RENARD Laurent @lorenzofox3 Nov 06 2015 02:27
https://github.com/petkaantonov/bluebird has pretty nice api especially if you like functionnal style programming
Devin Despain @dangerdespain Nov 06 2015 02:28
yeah, that's what I'm building for
I actually renamed the plugin I'm working on to ah-bluebird-plugin so I don't have to deal with the others
I've chosen my horse
RENARD Laurent @lorenzofox3 Nov 06 2015 02:37
if you add on top of it a functionnal programming library (with currying, etc) like rambda you can get things pretty nice
for example this code
handle sequelize database error (500) or any other uncaught
returns 404 if the product can't be found
returns 403 if the product does not belong to the currently logged in merchant
update the product with provided params
return the updated product
so basically a lot in a very explicit and concise way
exports.updateProduct = {
name: 'updateProduct',
description: 'I update a product',
run: handle(function (api, data) {
return api.models.product.findById(data.params.id)
.then(f.eventuallyThrow('could not find the product'))
.then(f.eventuallyForbid(data.requester.activeMerchant))
.call('updateAttributes', data.params)
})
}
Devin Despain @dangerdespain Nov 06 2015 02:41
that's sexy
Evan Tahler @evantahler Nov 12 2015 13:08
New version up!
https://github.com/evantahler/actionhero/releases/tag/v12.2.1
This message was deleted
WebSocket Re-Use
Rather than reuse an existing Primus transport, we should create a new one. This will help solve double-callbacks and double-emits which would otherwise be confusing.
by @evantahler via evantahler/actionhero#697
Misc
Testing with node v5.x. It passes!
Update dependent packages to their latest versions.
Documentation updates
Evan Tahler @evantahler Nov 12 2015 14:22
I also just wrote a bunch of notes about running actionhero in production, which I've added to the docs site
evantahler/actionhero#701
Chad Robinson @crrobinson14 Nov 12 2015 15:59
Guys I think there's a breaking change here. node-uuid 1.4.6 was just released and all of a sudden our npm install broke for actionHero.
Sent PR evantahler/actionhero#702
Haven't tested it yet, doing that now
Chad Robinson @crrobinson14 Nov 12 2015 16:14
Confirmed, this fixes it although better still I forked AH and changed all the deps to use ^ rather than a fixed version.
Evan Tahler @evantahler Nov 12 2015 16:49
new version of AH up with just the UUID version change
send in a PR with relative dependanices!
Chad Robinson @crrobinson14 Nov 12 2015 16:52
OK happy to, was just trying to keep it small since I'm not running the full test suite here. But Travi has our backs right? :)
This message was deleted
Chad Robinson @crrobinson14 Nov 12 2015 17:04
Sent. Go Travis Go
Zhonghai Zuo @zhhz Nov 12 2015 20:15
Hi, anyone knows how to make mocha watch running? I'm using the --watch option, but it fails...
Evan Tahler @evantahler Nov 13 2015 07:32
Probably something like NODE_ENV=test ./node_modules/.bin/mocha --watch
Angelo Rodrigues @AngeloR Nov 13 2015 07:36
if you have it installed globally just a “mocha -w [path/to/test/dir]” will do.
Zhonghai Zuo @zhhz Nov 13 2015 16:41
@evantahler @AngeloR Thanks guys. much appreciate it.
Evan Tahler @evantahler Nov 14 2015 19:31
@/all I've remade the actionherojs.com/docs site. Hopefully now it is more readable and has more accessable examples. Let me know your thougths! http://www.actionherojs.com/docs
Neil Craig @neilstuartcraig Nov 15 2015 02:25
That’s really cool @evantahler - much clearer and easier to find things with it all being on one page. Nice work sir
peterkingsbury @peterkingsbury Nov 15 2015 04:10
Looks great, Evan! I'd like to make one suggestion; I typically use the site to quickly look up api call parameter structure. The previous site layout included all api calls in a sort of mini "table of contents" per page, but the current site does not, requiring one to vertically scroll-and-search for the section in question. Any way to accommodate that?
The
Evan Tahler @evantahler Nov 15 2015 20:39
@peterkingsbury Hmm, I guess we could add back a section like this https://github.com/evantahler/actionhero/blob/master/docs/docs/methods.md which lists all the public methods out... but that would still be tricky to navigate (wouldn't really fit in the left nav). Have you played with the search bar?
good feedback!
peterkingsbury @peterkingsbury Nov 16 2015 06:40
@evantahler I think we agree that putting an API call list in the left-hand-side nav menu would be a bit wonky! I was more thinking of a hotlist immediately below a section header in the main area (e.g. when you click on Chat, the center area's "Chat" heading , above "General", would have the list of API calls immediately below it). Aside from this, I really like the new layout. It will be much easier to work with the docs!
peterkingsbury @peterkingsbury Nov 16 2015 06:56
Playing around further, it looks like Methods is quite sufficient for my needs. :-)
peterkingsbury @peterkingsbury Nov 16 2015 07:05
Is there an onClick throttler? My OCDness can't click on doc menu links as quickly as I'd like.
Evan Tahler @evantahler Nov 16 2015 10:50
Haha, nope. just a lot of text to parse through
so while there is work to be done on the site, it does seem to be a general improvment
I'll merge it :D
Evan Tahler @evantahler Nov 16 2015 15:41
New Release! https://github.com/evantahler/actionhero/releases/tag/v12.2.3
Update requirements to compatible-with
This changes the package requirements to compatible-with deps instead of hard-coded version numbers. Hopefully this will help prevent immediate failures if packages get unpublished in the future, like node-uuid 1.4.3 did.
by @crrobinson14 via evantahler/actionhero#703
fix web+connection memory leak
Update the web server to fix a memory leak (introduced via evantahler/actionhero#689) which caused connections to be destroyed (and stay in RAM) on some operating systems + node versions.
by @evantahler via evantahler/actionhero#705
Oh, and we have a new documentation website! Check out http://www.actionherojs.com/docs
peterkingsbury @peterkingsbury Nov 17 2015 07:58
would it be possible for generate??? to perform the equivalent of mkdir -p for actions which include path information (for applying a kind of namespacing to actions, tasks etc) ?
Evan Tahler @evantahler Nov 17 2015 13:34
Anything is possible!
Have a more detailed example?
I think adding a --path flag to generate would be fine
randomnerd @randomnerd Nov 18 2015 20:19
hey there! how do you push events to connected clients with actionhero?
Evan Tahler @evantahler Nov 18 2015 22:52
check out connection.send http://www.actionherojs.com/docs/#chatting-to-specific-clients
that works if everything is on the same server
This message was deleted
and if you have a cluster, you will want to check out api.connections.apply http://www.actionherojs.com/docs/#rpc
randomnerd @randomnerd Nov 19 2015 02:03
@evantahler yep figured it out, this is what i was doing: https://gist.github.com/randomnerd/4214c1dc00e51bce7e35
sending direct message to specific user regardless which node he’s connected to or how many connections he has
Evan Tahler @evantahler Nov 19 2015 09:03
Neat! Happy that we have tools that work for you!
randomnerd @randomnerd Nov 19 2015 09:08
@evantahler yep, looks nice so far
trying to implement something like Meteor’s data subscriptions now
there was no active development on AH’s client library as far as i see
Evan Tahler @evantahler Nov 19 2015 09:26
Which one? The web socket client is updated fairly often
randomnerd @randomnerd Nov 19 2015 09:26
https://github.com/evantahler/actionhero/blob/master/client/actionheroClient.js
Evan Tahler @evantahler Nov 19 2015 09:27
That's the one!
randomnerd @randomnerd Nov 19 2015 09:29
perhaps it should be documented somehow, wondering what .configure method is for
Evan Tahler @evantahler Nov 19 2015 09:32
It's internal. Mostly has to do with loading ids and reconnecting
randomnerd @randomnerd Nov 19 2015 09:41
another idea is that websocket events should have sort of ids so the client can clearly identify which response was to which request
Evan Tahler @evantahler Nov 19 2015 09:44
Check out how the socket server handles this with response ids. Primus abstracts this, but it can be exposed up
Trinh Minh Cuong @TechMaster Nov 21 2015 01:10
I start ActionHero using npm start. It only start web at port 8080 but does not start socket server at 5000. How can I start socket server?
I tried to connect to ActionHero SocketServer at port 5000 using ActionHero Client but failed
peterkingsbury @peterkingsbury Nov 21 2015 03:45
@TechMaster look through config/servers, I think what you're looking for is in socket.js
Trinh Minh Cuong @TechMaster Nov 21 2015 05:05
@peterkingsbury : thanks, I just enable Socket server. It works now
Evan Tahler @evantahler Nov 24 2015 10:21
yay!
Evan Tahler @evantahler Nov 25 2015 00:17
It's that time again! @/all If you are a company using actionhero... I want to list you here! http://www.actionherojs.com/learn-more/ Let me know!
randomnerd @randomnerd Nov 25 2015 04:51
@evantahler having a race condition with messaging here
my action leads to a message being sent to client’s websocket, and its being sent earlier than action’s data.response, so the client takes first message on socket as response to the action and its not the right one
Evan Tahler @evantahler Nov 25 2015 13:17
why are you sending a message to the client separately, and not just using the action's response?
unless you have an HTTP action yeilding a WS message
randomnerd @randomnerd Nov 25 2015 13:17
because action leads to a broadcast
Evan Tahler @evantahler Nov 25 2015 13:18
ahh
can you explain why the order maters?
randomnerd @randomnerd Nov 25 2015 13:19
i’m getting broadcasted message at the action’s callback
Evan Tahler @evantahler Nov 25 2015 13:19
either way, if you want to gaurntee an "order" (which is not really easy in distrubuted systems like this), you can use the payload to denote the type of message
I don't think I understand
the client making the action request doesn't want the normal callback?
randomnerd @randomnerd Nov 25 2015 13:19
action sends a response, like data.response.success = true
Evan Tahler @evantahler Nov 25 2015 13:20
sure
randomnerd @randomnerd Nov 25 2015 13:20
so {success:true} should land into the client’s action callback
Evan Tahler @evantahler Nov 25 2015 13:20
client.action() should always get the right callback
is it not?
and in parallel you'll get client.on(say) from your broadcast
1 event, 1 callback in your case
randomnerd @randomnerd Nov 25 2015 13:21
nope, if i broadcast a message the message gets into the callback instead of {success: true}
Evan Tahler @evantahler Nov 25 2015 13:22
huh
can you share some test code?
open an issue with it!
also, share your call to the broadcast method
Nick Collins @ndcollins Nov 25 2015 21:33
This message was deleted
Angelo Rodrigues @AngeloR Nov 26 2015 10:11
how do we deal with array inputs? IE: I have form data that looks like this "type=test-api&url_fragment=test-url&access%5B%5D=mssql&access%5B%5D=postgresql&access%5B%5D=characters&url_host=domain.com” but setting the required param “access” in my inputs still returns an error :/
Angelo Rodrigues @AngeloR Nov 26 2015 11:47
ah I see. you must set the param name as “access[]” since that is how it appears in the actual request. I haven’t reviewed of the existing source, but would a PR to support this be ok?
As in: convert array form submissions into an array based on the root name instead of the array designation used in the http spec?
Angelo Rodrigues @AngeloR Nov 26 2015 12:06
I
I’d rather submit it as something for discussion since it does change the core functionality for this.
Evan Tahler @evantahler Nov 26 2015 13:06
Just saw your issue. Seems like a fine PR!
I left some questions for you.
We are talking about evantahler/actionhero#709 for reference.
Angelo Rodrigues @AngeloR Nov 26 2015 14:04
I’m just testing how other frameworks are handling it to see if there’s an accepted standard for how various situations are handled.
Evan Tahler @evantahler Nov 26 2015 15:25
Cool! Let me know what you find out.
Kerim Incedayi @cevatkerim Nov 26 2015 20:05
@evantahler feel free to add our company to the list. Let me know if you need anything for this.
Evan Tahler @evantahler Nov 26 2015 21:26
What's your company?
Kerim Incedayi @cevatkerim Nov 26 2015 22:31
ModoPayments
Evan Tahler @evantahler Nov 27 2015 10:48
@cevatkerim yay, thanks! evantahler/actionhero@2a090e6
Chris Capobianco @ccapo Nov 28 2015 11:30
Anyone else notice strangely formatted resque keys in redis when scheduling tasks?
127.0.0.1:6379> keys resque:timestamps:*
1) "resque:timestamps:{\"class\":\"myTask\",\"queue\":\"default\",\"args\":[{}]}"
I'm using version 12.2.3 of actionhero, and this occurs even if I downgrade to 12.0.0
I also tried to enqueue a task in an initializer and I still get such a key, any help would be appreciated.
Evan Tahler @evantahler Nov 28 2015 12:59
Those keys are used for the delay counters so you can find and remove delayed jons
Chris Capobianco @ccapo Nov 28 2015 14:13
@evantahler thanks
Evan Tahler @evantahler Nov 29 2015 10:00
New version up!
https://github.com/evantahler/actionhero/releases/tag/v12.3.0
Use QS to enable array and complex param parsing for the web server
The [qs](https://github.com/hapijs/qs) package (originally from TJ Holowaychuk, and now maintained by the Hapi.JS team) is an excellent query-string parsing library made to expand upon and replace node's built-in url.parse. It handles more esoteric cases like merging ?collection[]=first&collection[]=second into an array containing both 'first' and 'second'. More importantly, It allows you to configure how to handle special cases of posting object, deeply nested params, etc.
Actionhero maintains its stance of shipping with support for these advanced/fancy/not-in-spec params disabled, but now you can customize this behavior as you see fit via the new api.config.servers.queryParseOptions, which will be passed to the qs parser.
via @evantahler by evantahler/actionhero#711
Winston 2.0
Upgrade actionhero to use winston v2.x.x as our logger.
This new version of Winston fixes a number of long-standing bugs with how they handled log levels. Winston now confirms to the standard RFC 5424, which matches both node itself and npm. This allows us to remove our custom loggers in favor of the defaults.
Reverting to a uniform logging specification required that we remove actionhero's custom trace log level, which is a reversion of evantahler/actionhero#595, which we added in February of this year. This means that if you run your actionhero server with the log level of debug, you will now see messages which had been previously tagged as trace.
I expect more conversation on this topic to unfold. This release has been cut before that so that we can be starting from a common RFC baseline, and move up from there.
You can now customize the logger's behavior You can customize these via api.config.logger.levels and api.config.logger.colors. See Winston's documenation for more information. This will allow you do bring back trace and other custom log levels for your actions/initializers.
Documentation Fixes and Updates
With the launch of our new documentation site (www.actionherojs.com/docs), there were bound to be some typos and mistakes. Thanks to the following folks for helping to fix the bugs!
@randomnerd via evantahler/actionhero#708
@AngeloR via evantahler/actionhero#710
and @crazy4groovy and @slattery for pointing out some mistakes
Remember, if you want to contribute to the public site of docs, to not work against the gh-pages branch. That is built automatically from master/site. You can read more about the public site's build process here: https://github.com/evantahler/actionhero/blob/master/site/README.md
Angelo Rodrigues @AngeloR Nov 29 2015 11:26
oh man. this is an awesome release. time to upgrade.. we use winston as part of the underlying log transport system, so now we can just swap out the winston base for our system
Evan Tahler @evantahler Nov 29 2015 12:54
progress
Anders Munk Petersen @auro1 Nov 29 2015 13:39
How do I debug redis settings?
I get things like this on Heroku: 2015-11-29 19:17:09 - emerg: Redis Error (client): Error: Ready check failed: NOAUTH Authentication required.
I'm sending it a REDIS_URL and I also tried with a REDISCLOUD_URL
Anders Munk Petersen @auro1 Nov 29 2015 13:46
exports.default = {
redis: function(api){
var redisDetails = {
// Which channel to use on redis pub/sub for RPC communication
channel: 'actionhero',
// How long to wait for an RPC call before considering it a failure
rpcTimeout: 5000,
// which redis package should you ise?
package: 'fakeredis',
// Basic configuration options
//host : process.env.REDIS_HOST || '127.0.0.1',
//port : process.env.REDIS_PORT || 6379,
//database : process.env.REDIS_DB || 0,
//url: process.env.REDIS_URL || "",
}
if( process.env.FAKEREDIS === 'false' || process.env.REDIS_HOST !== undefined ){
redisDetails.package = 'redis';
// there are many more connection options, including support for cluster and sentinel
// learn more @ https://github.com/luin/ioredis
redisDetails.options = {
url: process.env.REDISCLOUD_URL || ""
};
}
return redisDetails;
}
}
Chad Robinson @crrobinson14 Nov 29 2015 17:32
Whoah, nice doc update!
@auro1 You need to pass in a Redis auth password to connect to Heroku. They should have given you one. I switched to ioredis but IIRC in node-redis it's auth_pass: 'xyz...'. Or you can put it in your URL like redis://user:pass@host:port. See https://github.com/NodeRedis/node_redis
I'm pleased to report I'll be using ActionHero in another new project. Name forthcoming. I'll share when able.
Evan Tahler @evantahler Nov 29 2015 18:35
Tight!
lysyi-alex @lysyi-alex Nov 30 2015 06:47
how transfer file with actionheroClient in actionhero, use TCP/IP sockets? Please, answer me.
Evan Tahler @evantahler Nov 30 2015 08:22
In actions, you want data.connection.sendFile() http://www.actionherojs.com/docs/#sending-files-from-actions
That said, for TCP you'll need to probably also send a break char sequence when the file is done sending.
Angelo Rodrigues @AngeloR Nov 30 2015 09:53
is there currently a way to upgrade an existing installation of actionhero?
Anders Munk Petersen @auro1 Nov 30 2015 16:51
So now I got it working - thanks @crrobinson14
What library do you people use for managing object models? I'm intending to use PostgreSQL as backend.
Evan Tahler @evantahler Nov 30 2015 17:02
@auro1 sequelize is the bomb-diggity
http://sequelize.readthedocs.org/en/latest/
@AngeloR if you are within the same major version, just bumping the version in your package.json should be fine
if not, make a new project from scratch and copy in your actions/initilizers/etc
Anders Munk Petersen @auro1 Dec 01 2015 14:54
hmm. So with Sequelize, I would create models in a /models folder and I guess initialize it in an initializer?
Evan Tahler @evantahler Dec 01 2015 14:59
Yep!
Anders Munk Petersen @auro1 Dec 01 2015 15:00
Oh. That seems simple enough
Evan Tahler @evantahler Dec 01 2015 15:00
There is also a plugin some folks maintain
Anders Munk Petersen @auro1 Dec 01 2015 15:00
Oh?
https://github.com/evantahler/ah-sequelize-plugin ?
Anders Munk Petersen @auro1 Dec 01 2015 15:05
That's funny.
When I try to install ah-sequelize-plugin on windows, i get: scripts was not recognized as an internal or external command or program
auro@AURO-PC C:\Users\auro\Documents\api-v2
npm install ah-sequelize-plugin --save
npm WARN package.json my_actionhero_project@0.0.1 No repository field.
npm WARN package.json my_actionhero_project@0.0.1 No license field.
\
ah-sequelize-plugin@0.7.2 postinstall C:\Users\auro\Documents\api-v2\node_modules\ah-sequelize-plugin
scripts/postinstall.js
'scripts' blev ikke genkendt som en intern eller ekstern kommando,
et program eller en batchfil.
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\Program Files (x86)\nodejs\node.exe" "C:\Program Files (x86)\nodejs\node_modules\npm\bin\npm-cli.js" "install" "ah-sequelize-plugin" "--save"
npm ERR! node v4.0.0
npm ERR! npm v2.14.2
npm ERR! code ELIFECYCLE
npm ERR! ah-sequelize-plugin@0.7.2 postinstall: scripts/postinstall.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ah-sequelize-plugin@0.7.2 postinstall script 'scripts/postinstall.js'.
npm ERR! This is most likely a problem with the ah-sequelize-plugin package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! scripts/postinstall.js
Anders Munk Petersen @auro1 Dec 01 2015 15:12
@evantahler could you change https://github.com/evantahler/ah-sequelize-plugin/blob/master/package.json the postinstall to: "scripts": {
"postinstall": "node scripts/postinstall.js"
}
@evantahler made a PR evantahler/ah-sequelize-plugin#25
turanchox @turanchox Dec 02 2015 07:18
which parameters can take blockedConnectionTypes in actions?
Evan Tahler @evantahler Dec 02 2015 07:26
Just the action itself
turanchox @turanchox Dec 02 2015 07:47
TCP, webSocket etc?
I must blocked all only TCP
Evan Tahler @evantahler Dec 02 2015 08:17
yeah, it's the name of the server. So you would do action. blockedConnectionTypes = ['web','websocket']
you can also enable=false those servers entirely if you aren't using them in config
DefunctExodus @DefunctExodus Dec 03 2015 06:44
So this may be a stupid question , what is the recommended method for defining a validator or formatter so that they can be reused in different actions.
jamesmr89 @jamesmr89 Dec 03 2015 14:16
Does actionhero support remote syslog logging by default?
Evan Tahler @evantahler Dec 03 2015 17:44
The Winston logger (which we use) does
https://github.com/winstonjs/winston-syslog
Evan Tahler @evantahler Dec 03 2015 22:45
@DefunctExodus since they are all sync methods, you can have a shared collection you require into each action
seems clean enough
DefunctExodus @DefunctExodus Dec 04 2015 07:34
@evantahler Yeah that is what we are doing, I just wanted to make sure I was not overlooking something that was built in to ah, Thanks.
jamesmr89 @jamesmr89 Dec 04 2015 09:30
@evantahler I'm trying to add a require statement to get winston-syslog working but not sure where I should do this, I can see in conf/logger.js where I add the transport once its in place but not sure where I need to add the require statement to add Syslog transport to winston so i an use it in logger.js. Does that make sense?
Chad Robinson @crrobinson14 Dec 06 2015 17:59
@evantahler Minor detail, even if I disable "anotherRoom" it seems like the core chatRoom initializer creates it anyway?
@jamesmr89 We use winston as provided by AH plus winston-papertrail to remote-log to PT. They're great.
Chad Robinson @crrobinson14 Dec 06 2015 18:05
In our config we do function(api, winston) { winston.transports.Papertrail = require('winston-papertrail').Papertrail;
Which is requiring it pretty late in the game. I haven't checked to see if this is still required but we had trouble with just flat including it at the top of config files in earlier versions. It seems like there's some dep-conflict where when you install a Winston plugin, it forces you to install (because it depends-on) Winston itself at the top level of your node_modules. But AH also includes it and maybe not the same one when it gets loaded.
Requiring it late makes sure it sees the right one when the plugin loads.
Evan Tahler @evantahler Dec 07 2015 00:28
@crrobinson14 be sure that startingChatRooms: {} rather than null or undefined. If it's !true, then we'll source the default config which has those rooms in there
@crrobinson14 nice hint!
Muhamed Krlić @l0oky Dec 07 2015 12:28
Why is actionhero not popular by now?
This module should be booming the markets
Evan Tahler @evantahler Dec 07 2015 12:31
Because you haven't told everyone you know yet!
Serious question: I don't have a good answer :(
Muhamed Krlić @l0oky Dec 07 2015 12:32
Wow, the Evan Tahler himself! Yeah well It could be explained since the project just started this year? :D
Evan Tahler @evantahler Dec 07 2015 12:32
Y'all should be evangelizing! Write blog posts and examples! Give talks!
I think it's 3 years old... Su be node v0.6
Muhamed Krlić @l0oky Dec 07 2015 12:33
Really?
Evan Tahler @evantahler Dec 07 2015 12:33
*since node v0.6
Muhamed Krlić @l0oky Dec 07 2015 12:33
wow, well that scares me a bit
Evan Tahler @evantahler Dec 07 2015 12:37
https://github.com/evantahler/actionhero/commits/master?page=66
2011!
Ha! It used to be called "DaveAPI"
Why is that scary?
Muhamed Krlić @l0oky Dec 07 2015 12:40
That not much of the internet actually has heard of actionhero?
Is it because of some lacking feature or..?
Evan Tahler @evantahler Dec 07 2015 12:44
I assume it's mostly because there are a lot of other tools. It's a crowded space!
It's also doing some stuff that isn't that mainstream yet. WS, multi transport, etc
For your basic site, express still shines!
Muhamed Krlić @l0oky Dec 07 2015 12:46
I actually needed multi transport a month ago before I knew actionhero
then my mouth just wide opened when I saw actionhero
Evan Tahler @evantahler Dec 07 2015 12:46
Nice!
Now write that In a blog post :)
Muhamed Krlić @l0oky Dec 07 2015 12:47
I needed tcp to ws and vice versa
Evan Tahler @evantahler Dec 07 2015 12:47
That's how you get popular I guess
Muhamed Krlić @l0oky Dec 07 2015 12:47
I am not really a good blog writer.. But I think I know who can help us
You know toptal.com?
Evan Tahler @evantahler Dec 07 2015 12:47
(Seriously, I'll help you if you want)
Nope, checking it now
Muhamed Krlić @l0oky Dec 07 2015 12:48
It's a big freelance company
Evan Tahler @evantahler Dec 07 2015 12:48
Yeah, looks cool
Muhamed Krlić @l0oky Dec 07 2015 12:48
I personally know the Lead Technical Editor there. He manages their blog
Evan Tahler @evantahler Dec 07 2015 12:49
Nice!
Muhamed Krlić @l0oky Dec 07 2015 12:49
I'll see what I can do
Evan Tahler @evantahler Dec 07 2015 12:49
Awesome.
Muhamed Krlić @l0oky Dec 07 2015 12:49
And tell the bloggers to contact you here If they want to...
jamesmr89 @jamesmr89 Dec 07 2015 15:48
is there a good way to gracefully shutdown actionhero from within itself? I'm looking to have a way to shut down an instance via an initializer
Evan Tahler @evantahler Dec 07 2015 18:17
http://www.actionherojs.com/docs/#programatic-use-of-actionhero
Yep!
Chad Robinson @crrobinson14 Dec 07 2015 19:17
@evantahler Not sure it's working that way (starting chat rooms). Because I have set startingChatRooms: { 'defaultRoom': {} } and it still creates otherRoom.
It's definitely truthy.
Muhamed Krlić @l0oky Dec 08 2015 05:30
@evantahler Why do I feel like Chat rooms should be a plugin instead of being implemented into actionhero? I mean I am probably wrong because I don't really know what's the concept around ws rooms in actionhero. Is it for you know.. chat or maybe role based room access so you can call actions?
Nick Collins @ndcollins Dec 08 2015 07:00
Is there a way to trigger resque to immediately poll for pending tasks? I’d like to have some tasks in my app that execute immediately when enqueued
Muhamed Krlić @l0oky Dec 08 2015 07:20
^
Evan Tahler @evantahler Dec 08 2015 08:20
Rooms in general is a metaphor for broadcasting messages to groups of people. Maybe server-client or client-client. It's a pretty important pattern for servers which are stateful
You don't actually have to "chat" per-se
So resque sleeps for 5s if there is no work to do. If there is work to do it won't sleep. You can change the sleep interval with a settting
Just keep in mind that you will be adding load to redis (and your worker node) the more often you poll
I'll take a look at those starting rooms in a bit.
Can you open a GitHub issue?
Evan Tahler @evantahler Dec 08 2015 08:59
@crrobinson14 I can't seem to reproduce that. In a new AH project, and checking the keys in redis, if startingChatRooms = {} no rooms get created
NizarBlond @NizarBlond Dec 09 2015 08:24
hello
is this room active? :)
Evan Tahler @evantahler Dec 09 2015 08:25
Sure is!
Muhamed Krlić @l0oky Dec 09 2015 08:25
Yeah :D
Evan Tahler @evantahler Dec 09 2015 08:25
What's up?
NizarBlond @NizarBlond Dec 09 2015 08:26
awesome, i some how found actionhero js while looking for implementing node js workers for web crawling
i usually use sails js, but that's too heavy for such project.
Evan Tahler @evantahler Dec 09 2015 08:27
Cool.
Muhamed Krlić @l0oky Dec 09 2015 08:27
@NizarBlond Web crawling? You like hacking too then? :D
Evan Tahler @evantahler Dec 09 2015 08:27
Well, good luck! Have you found www.actionherojs.com/docs? That's probably the best place to learn about workers.
NizarBlond @NizarBlond Dec 09 2015 08:28
@l0oky i used to, now we grew up and became professionals haha
@evantahler yeah i already read it several times to be honest
Muhamed Krlić @l0oky Dec 09 2015 08:28
Yeah professional web crawling
:P
NizarBlond @NizarBlond Dec 09 2015 08:29
my question is more architectural, my vision is to have a web-worker and N workers that read urls from Redis or any data store, do background jobs, update some mongodb and Redis/FirebaseIO for real time results (websockets).
Evan Tahler @evantahler Dec 09 2015 08:30
You guys found the cheerio lib? That + request is really all you need for a basic crawler
Wicked fast tkk
Too*
Muhamed Krlić @l0oky Dec 09 2015 08:30
Cool I'll look it up
NizarBlond @NizarBlond Dec 09 2015 08:30
yeah, i am not talking functional. Cheerio is for crawling and functional purposes.
I want to know how to create the cluster
The best practices, any tutorials, etc..?
I can create the crawling application using actionhero, then duplicate it on several servers and run a scheduler to wake it up and look for data to crawl. No?
Evan Tahler @evantahler Dec 09 2015 08:32
There are some general notes here. http://www.actionherojs.com/docs/#best-practices
Sure!
And you don't need the scheduler
Have some nodes act as the http server
And others just running workers.
They'll get the jobs off redis and work them as they come in
NizarBlond @NizarBlond Dec 09 2015 08:33
so the same node has the web interface and workers on the background?
Evan Tahler @evantahler Dec 09 2015 08:33
You can, but to scale it's best to split them ip
You won't want the workers blocking the event loop
NizarBlond @NizarBlond Dec 09 2015 08:34
Surely not.
Evan Tahler @evantahler Dec 09 2015 08:34
Or, on the same host run some http servers and some worker servers
Just be sure you have enough CPU cores (and ram)
NizarBlond @NizarBlond Dec 09 2015 08:34
I have minimal web requests. They should simply write data to Redis/Mongo and "wake up" worker nodes, someway.
Evan Tahler @evantahler Dec 09 2015 08:34
But all the redis communication is built in
NizarBlond @NizarBlond Dec 09 2015 08:35
So redis will wake up my node js workers? I don't get it.
Evan Tahler @evantahler Dec 09 2015 08:36
It's a queue and the workers poll
NizarBlond @NizarBlond Dec 09 2015 08:38
Yes, but then how will the workers nodes communicate and "wake up"? web-workers for example are listening to some port so it is alive all the time. Workers on the other hand aren't, no?
Sorry for the naive question, quite new to node js workers world.
I mean, how will I tell the workers to keep polling the redis or open some websocket?
Evan Tahler @evantahler Dec 09 2015 09:06
as long as your actionhero server is running, and you have it configured to have at least one worker
the workers poll for jobs from resque, sleep a little, and try again
we use the node-resque package under the hood to manage it
https://github.com/taskrabbit/node-resque
you can also see actionhero's worker options here: https://github.com/evantahler/actionhero/blob/master/config/tasks.js, which might make a little more sense
NizarBlond @NizarBlond Dec 09 2015 09:08
so i should write 2 actionshero apps, web-server and worker?
Evan Tahler @evantahler Dec 09 2015 09:08
you can use the same app
but when you deploy it, deploy it in 2 modes
http://www.actionherojs.com/images/cluster.png
check that image out
NizarBlond @NizarBlond Dec 09 2015 09:09
yes exactly what i was looking at
Evan Tahler @evantahler Dec 09 2015 09:09
the web server and the worker server can be the same applicaiton (same git repo, etc)
just change the config
some have workers running, some don't
and some are under the LB, some aren't
again, you can run both HTTP and workers from the same intance to get started
but as you scale, you'll probably need to split them out
as long as both your HTTP requests and worker jobs aren't CPU-intensive, it doesn't mater to node what kind of request they are filling, HTTP, web socket, a worker, job... it's all good!
which is basically the philosophical core of actionhero
NizarBlond @NizarBlond Dec 09 2015 09:11
ah, eventually, each worker / http should be on a separate server instances, right?
Evan Tahler @evantahler Dec 09 2015 09:11
eventually, yeah
NizarBlond @NizarBlond Dec 09 2015 09:12
my http requests are minimal.
it is not open to public. private app.
i just want to be ready to say X-workers are not enough, I need X+Y
and scale up immediately.
Now regarding background jobs, say if they use async library (caolan), how do I know / manage how many jobs should run in parallel? maxTaskProcessors?
I just keep raising the number and see the results?
Evan Tahler @evantahler Dec 09 2015 09:29
"tasks" in actionhero are not meant to be inline with requests
you enqueue them and then are worked by (optionally) seperate processes
so using the async lib within a request chain (action) is probably a bad idea
you enqueue them from requests (or other tasks)
but yeah, just keep adding more workers as you need them (and adding more servers)
Muhamed Krlić @l0oky Dec 09 2015 09:31
I like the cluster first idea behind actionhero :)
NizarBlond @NizarBlond Dec 09 2015 09:37
wait, what are you refering to by "action" here is an http request, and task is the background job (time-consuming)?
I plan to use async in tasks, the time consuming. Once I downloaded the HTML code, "extract title" and "extract links" simultaneously.
Muhamed Krlić @l0oky Dec 09 2015 09:39
wow that sounds like a cool web crawler
NizarBlond @NizarBlond Dec 09 2015 09:39
haha, it is an example of what I can do with the home page html.
Muhamed Krlić @l0oky Dec 09 2015 09:39
OSI
Open Source Intelligence ;)
YKWIM
Muhamed Krlić @l0oky Dec 09 2015 10:11
Is action flexible enough to call actions from code? I guess that's anti-pattern?
I mean ofcourse it is. Just saying. :D
Krishna Glick @krishnaglick Dec 09 2015 10:46
Anyone have a recommendation for an ORM (using PostgreS)
Muhamed Krlić @l0oky Dec 09 2015 10:46
sequelize
@krishnaglick https://github.com/evantahler/ah-sequelize-plugin
Krishna Glick @krishnaglick Dec 09 2015 10:50
ty!
Muhamed Krlić @l0oky Dec 09 2015 10:52
How do I check If my plugin has been loaded? I wanted to load ah-jwtauth2-plugin and api.jwtauth is undefined..
oh. I am calling it in my initializer is my plugin loaded by before the initializers
?
Jarvin_Guan @Jarvin-Guan Dec 10 2015 05:17
anyone here?
Muhamed Krlić @l0oky Dec 10 2015 06:50
@Jarvin-Guan Yes :)
Muhamed Krlić @l0oky Dec 10 2015 07:02
Can I check If Actionhero loaded a plugin correctly?
I want to load 'ah-jwtauth2-plugin' but Its object doesn't exist in api object...
Evan Tahler @evantahler Dec 10 2015 07:19
Can you link the source of that plugin? Does it modify the Ali object?
Either way, that's a good way to check.
Muhamed Krlić @l0oky Dec 10 2015 07:20
Api object is modified by the looks of it. one sec
Evan Tahler @evantahler Dec 10 2015 07:20
You ave it both npm installed and listed in the plugin's config file?
Muhamed Krlić @l0oky Dec 10 2015 07:20
yes
https://github.com/ifavo/ah-jwtauth-plugin
api.jwtauth is undefinedhttps://gist.github.com/l0oky/a9e0221421c1fd9fa487#file-initializers_master-js-L6
I have a master.js file in my initializers and this api.jwtauth is undefined.. I am guessing api.jwtauth is initalized after my master.js
Muhamed Krlić @l0oky Dec 10 2015 07:29
ah-sequelize-plugin loads fine
Evan Tahler @evantahler Dec 10 2015 07:51
If you can load other plugin's fine, reach out to that packages developer I gues.
Maybe it's out of date
Muhamed Krlić @l0oky Dec 10 2015 07:52
I don't get why is Its jwtauth object undefined.
Evan Tahler @evantahler Dec 10 2015 07:54
Yeah, I think that was built for an older version of actionhero
He never calls "addMiddleware" anywhere
Shouldn't be too hard to update it.
Do a pull request for it!
Muhamed Krlić @l0oky Dec 10 2015 07:55
Hmm yeah. Something like a deprecated warning would be nice.
Yeah sure
Evan Tahler @evantahler Dec 10 2015 07:56
Assuming that package decipher still cares/works for that company/is alive, sure
Muhamed Krlić @l0oky Dec 10 2015 07:56
I'll learn more about making actionhero plugins along the way
It's never too late to do a fork
Evan Tahler @evantahler Dec 10 2015 07:56
Exactly!
Muhamed Krlić @l0oky Dec 10 2015 08:01
So api.actions was replaced by api.connections in the newer versions?
nevermind
there are specific objects for each feature
Muhamed Krlić @l0oky Dec 10 2015 08:11
@evantahler There is this addMiddleware. Does It count?
Evan Tahler @evantahler Dec 10 2015 08:15
Ahh, yep!
But that wouldn't modify the app object
That's something like api.actuons.middleware
Muhamed Krlić @l0oky Dec 10 2015 08:29
Yeah, I still fail to identify what's the issue.. Everything looks by the book
I think It's because I had a plugin earlier that used the same config file. Does npm have something like postUninstall script? To like revert all your plugin files. That would be cool.
Muhamed Krlić @l0oky Dec 10 2015 08:39
No that wasn't the problem.
I really don't get it api.jwtauth is directly modified in the plugin initializer.
Even api.config.jwtauth is present.
Muhamed Krlić @l0oky Dec 10 2015 09:51
@evantahler Where is the part of the code responsible for loading plugins into actionhero?
I would like to add an api.log on plugin load
Evan Tahler @evantahler Dec 10 2015 14:46
It's in the configLoader
Muhamed Krlić @l0oky Dec 11 2015 10:25
Is ah-sample-plugin updated for newer actionhero versions? I can't see a difference or something that is missing from this ah-jwtauth2-plugin. I am having trouble with this plugin as It doesn't modify api.jwtauth object as It's supposed to at all. What is It missing?
Krishna Glick @krishnaglick Dec 11 2015 16:32
I'm trying to integrate ah-sequelize into my AH project but I feel the documentation is lacking. I create my models in the models folder, but where do I hook the model creation into the app, and where do I define associations? Just associations.js in the models folder?
Krishna Glick @krishnaglick Dec 11 2015 17:06
Does ActionHero not support ES6?!
Krishna Glick @krishnaglick Dec 11 2015 19:03
Well, import.
Krishna Glick @krishnaglick Dec 11 2015 19:16
Nope, I'm dumb.
Evan Tahler @evantahler Dec 11 2015 20:18
yeah, actionhero itself is still node v0.10 compatiable
at some point in 2016 we'll drop that
but for now, a lot of people are using it
you can of course write your actions (etc) however you want
@krishnaglick here's an example project to show I lay out my sequilize projects: https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf this one uses sequelize.sync, so it's lazy
here's a snipit with migrations:
Krishna Glick @krishnaglick Dec 11 2015 20:22
ty! I got it working on my end but there's likely a better pattern :)
Evan Tahler @evantahler Dec 11 2015 20:24
https://gist.github.com/evantahler/d9becae3da1ea57178db
actionhero is pretty loose on this kind of stuff (as there isn't an ORM built in), so it may try a little too hard to get out of the way :D
@l0oky nope, ah-sample-plugin is really out of date
Krishna Glick @krishnaglick Dec 11 2015 20:28
Oh, cool. It'll read my models for me. Awesome.
Evan Tahler @evantahler Dec 11 2015 20:31
the GLOB package is pretty great
@l0oky here's what I changed to "modernize" that sample packge evantahler/ah-sample-plugin@388aab1
Krishna Glick @krishnaglick Dec 11 2015 20:42
Dumb question, where in package.json do I put tasks.migrate: "sequelize db:migrate"?
Nathan @BoLaMN Dec 12 2015 03:27
Nice find with the connections leak @evantahler seems to have solved a lot of my issues, I was debugging all my tasks trying to figure out what was leaking for awhile now.
Muhamed Krlić @l0oky Dec 12 2015 05:50
@krishnaglick Why would you put that in package.json? You could put npm script migrate so you migrate with npm migrate for example. But It's uneccessary.
You can put it anywhere as long as It's in the main scope of the package.json object..
Muhamed Krlić @l0oky Dec 12 2015 06:09
@evantahler Sorry If I am asking too much, but can you point me on what is wrong with this plugin so api.jwtauth object is undefined? Thanks
Muhamed Krlić @l0oky Dec 12 2015 06:39
OK, now I am officially confused. When I run my actionhero app for the first time api.jwtauth is undefined, but when actionhero restarts Its self ( because actionhero was watching changes in files ) api.jwtauth suddenly is defined and works as excpected?! I am going to make a bug issue and try and make a project reproducing this error.
Nathan @BoLaMN Dec 12 2015 09:55
Maybe check your prioritys
See if the plugin is a lower priority then where you're calling it else it won't be defined yet.
Nathan @BoLaMN Dec 12 2015 10:08
I'm guessing it loads lowest to highest then alphabetically so if both plugins are priority 1000 and ones named a.js and the others named j.js then a.js can access j.js functions till after.
Cant*
Muhamed Krlić @l0oky Dec 12 2015 10:24
@BoLaMN Nope, I've put the priority to 999 and still the same.
Updated the repo. now
Evan Tahler @evantahler Dec 12 2015 11:23
check the github issue: evantahler/actionhero#715
start vs init
Muhamed Krlić @l0oky Dec 12 2015 11:24
That explains it.
Higher number === Higher priority?
Actually lower number === Higher priority..
Muhamed Krlić @l0oky Dec 12 2015 11:31
Thanks @evantahler, that was a great explanation on the difference between initialize and start!
Finally managed to get my app working after a few days! Phew, what a relief.
Nathan @BoLaMN Dec 12 2015 12:50
Maybe configure would be better wording for initialise
Muhamed Krlić @l0oky Dec 12 2015 12:50
^
Nathan @BoLaMN Dec 12 2015 12:52
I use configure, run and stop for my framework
Oh and execute
Muhamed Krlić @l0oky Dec 12 2015 12:52
@BoLaMN You have a framework?
Is it just me or is gitter showing 1 hour time difference on the right side between you and me?
Nathan @BoLaMN Dec 12 2015 12:57
Currently still finishing it up its a redis based micro service framework. So the api server just creates jobs in redis and waits for the worker servers to run the jobs and return the result. added a nice repl system to control the services and also a angular metrics dashboard shows the current status of the workers\jobs
Muhamed Krlić @l0oky Dec 12 2015 12:58
Cool, sounds like actionhero wouldn't need PM2 afterall. :D
I like PM2 because of Its statistics engine..
Nathan @BoLaMN Dec 12 2015 13:01
It's not actionhero... Similar concept but uses a different method for the redis integration and is all class based. I wrote a metrics system that handles timer and counter based analytics for the jobs
Muhamed Krlić @l0oky Dec 12 2015 15:30
It's really hard for me to debug where did I go wrong when for instance action.run doesn't call at all :/
How is that even possible? When I forget a next() in my middleware or what?
I have api.log('action ran!'); in my action.run and when I request my action i get a response but I don't have action ran! in my terminal.
Muhamed Krlić @l0oky Dec 12 2015 15:36
Just read the docs If a preProcessor has an error, the action will never be called.
My action is not called. But, actionhero doesn't report any errors.
Tan Li Hau @tanhauhau Dec 13 2015 00:51
Hi, I'm using the example from the actionhero tutorial, I'm trying to run the mocha test, but it seems to have [Error: connect ECONNREFUSED] when using request to localhost:8080/api, anyone know what is the problem?
the server is started using
var serverPrototype = require("actionhero").actionheroPrototype;
var server = new serverPrototype();
server.start(function(err, api){
done();
});
Muhamed Krlić @l0oky Dec 13 2015 04:03
@tanhauhau Funny, I had the same problem yesterday.
NizarBlond @NizarBlond Dec 13 2015 04:03
where is the point in the project where I configure an environment as a "web"-server or "worker"-server if I want to have both logics on the same actionhero app?
Tan Li Hau @tanhauhau Dec 13 2015 04:04
@l0oky So did you find out why it the end?
Muhamed Krlić @l0oky Dec 13 2015 04:04
No. But It worked once I ran my server normally on another terminal actionhero start. That's a bit hacky...
Tan Li Hau @tanhauhau Dec 13 2015 04:08
oh it work for me for that too.. but it isn't the correct way to do right?
Muhamed Krlić @l0oky Dec 13 2015 04:27
I guess not, but It works. Maybe the serverPrototype() is ran on another port?
Muhamed Krlić @l0oky Dec 13 2015 04:37
@tanhauhau Try connecting to this http://localhost:18080
I got this url like so :
actionhero.start(function(err, a){ api = a; url = 'http://localhost:' + api.config.servers.web.port; console.log('URL:',url); done(); })
actionhero.start(function(err, a){
api = a;
url = 'http://localhost:' + api.config.servers.web.port;
console.log('URL:',url);
done();
})
Alternatively just set this api.config.servers.web.port to what ever port you like.
api.config.servers.web.port = 8080;
before actionhero.start(...);
Scratch that you can't set the port like this
Muhamed Krlić @l0oky Dec 13 2015 04:42
just tried it
Muhamed Krlić @l0oky Dec 13 2015 05:21
Can action formatter cause action.run not to be called?
It seems when I return a JSON.parse from a input formatter that my action.run doesn't even get called.
Muhamed Krlić @l0oky Dec 13 2015 05:28
If my formatter only return param and not return JSON.parse(param) then my action.run gets called normally..
Muhamed Krlić @l0oky Dec 13 2015 06:09
@evantahler Can you explain why [this simple case scenario of formatter wouldn't work?
https://gist.github.com/l0oky/b15745575112513fa691
Evan Tahler @evantahler Dec 13 2015 10:18
@tanhauhau for the tutorial, the real server (npm start) and the test server run on diferent ports
this is managed via the config
https://github.com/evantahler/actionhero-tutorial/blob/master/config/servers/web.js#L88
@NizarBlond it's all about how you configure it. To be a 'web server' disable all taskProcessors and enable your servers... put this behind your load balancer. For a 'worker server', disable all servers (web, websocket, etc) and turn on some taskProcessors
other than that, the codebase can be the same!
@l0oky can you share valid and invalid inputs? In genral I've seen loadash (or underscore) do some weird things... my bet is that your console.log (https://gist.github.com/l0oky/b15745575112513fa691#file-not_working_action-js-L39
) is actually what's breaking
NizarBlond @NizarBlond Dec 13 2015 14:28
@evantahler how? from command line, how do I do this? this is the same app, where do i pass the config to disable as per app type?
@evantahler then, the "web"-server will run in a loop that listens to requests. what about the worker, who wakes it up to listen to redis queue incoming messages? cron jobs?
Evan Tahler @evantahler Dec 13 2015 14:55
Npm start in either case. Action hero is a node "process". It runs as its own pid. It checks redis on its own and listens for requests on its own. You don't need CRON
It's a deployment thing
Muhamed Krlić @l0oky Dec 13 2015 16:05
No @evantahler, I can remove lodash completely same issue will arise.
Muhamed Krlić @l0oky Dec 13 2015 16:12
Here's the updated gist.
Should I post an issue? I could recreate this issue and post it on github.
I'll do It tomorrow. For now the workaround is not to use input formatter :)
Oh and about the valid input:
// Valid inputs
{"name":"Test1","version":"0.0.1"}
{name:"Test1",version:"0.0.1"} // This one not tested
//Invalid input
Anything that is not JSON.
NizarBlond @NizarBlond Dec 14 2015 00:51
@evantahler so how do i "npm start" actionhero with "worker"-server config instead of the "web"-server which i guess is the default?
Muhamed Krlić @l0oky Dec 14 2015 05:10
@NizarBlond In package.json you can edit the scripts.start object and add your worker command with the following && ...
Oh I guess that's not what you wanted.
NizarBlond @NizarBlond Dec 14 2015 05:14
what's the worker command then? I don't get it. I want to run the worker where in loop or inner scheduler it starts listening to Redis, get messages and do the work.
Not sure why there isn't a clear example of how to do this basic stuff. Sorry, got confused.
Muhamed Krlić @l0oky Dec 14 2015 05:22
@NizarBlond Sorry misread your question a bit. :D
NizarBlond @NizarBlond Dec 14 2015 05:33
As far as I understand, you can run actionhero in 2 modes, as "web"-server process (http server, listens for requests) and another mode as "worker"-server.
Muhamed Krlić @l0oky Dec 14 2015 05:34
I think there is no any worker config in actionhero
NizarBlond @NizarBlond Dec 14 2015 05:35
what are the ./tasks for then?
Muhamed Krlić @l0oky Dec 14 2015 05:35
I can only guess since I know as much as you.
Documentation is good, but needs some polishing after we learn these stuff. I think that documentation needs to mention several times something to prove the point.
Giving more detailed information along the way.
@NizarBlond http://blog.evantahler.com/blog/actions-vs-tasks.html
NizarBlond @NizarBlond Dec 14 2015 05:51
Well, I read it, it explains the difference. I am asking about the deployment of the "task processing" nodes of the actionCluster in contrast to the "web"-nodes.
"web"-nodes run actions, which enqueue jobs (e.g. to Redis). Another server in the cluster, that isn't "web"-node but "worker"-node that runs time consuming tasks, will be listening (somehow) to Redis and get the enqueued job. The questions is, how to deploy this actionCluster and mark some "nodes" as "workers" and others as "web". How?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:28
I have confusing situation. Freshly generate actionhero, without any modification on config what so ever, is failed when start nodejs with debug
but without debug it is fine
it fails after notice: staring server websocket
it process exit unexpectedly
but if I set websocket disabled, the error is gone. and the actionhero can run with debug
I just notice this today. I have generated many actionhero project in the past, but this is the first time
May be some broken changes in Primus?
Muhamed Krlić @l0oky Dec 14 2015 08:31
Wait, freshly generated actionhero, right?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:31
Yes
Muhamed Krlić @l0oky Dec 14 2015 08:31
Did you npm install after generating?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:32
Yes
Muhamed Krlić @l0oky Dec 14 2015 08:32
You then actionhero start or npm start and it fails?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:33
if not debug mode, it run successfully
Here the screen shot
NizarBlond @NizarBlond Dec 14 2015 08:33
@evantahler my question above is so simple yet i cannot find a solution, please let me know what i should do. it is really confusing.
donnyhardyanto @donnyhardyanto Dec 14 2015 08:33
Muhamed Krlić @l0oky Dec 14 2015 08:34
@NizarBlond He'll read it ;) He's busy as it is
NizarBlond @NizarBlond Dec 14 2015 08:35
@l0oky I hope so, becoming frustrating, I almost know the doc by heart now lol
Muhamed Krlić @l0oky Dec 14 2015 08:35
I know the feeling.
We'll just have to wait, do some pushups in the meantime lol
@donnyhardyanto What version of actionhero are you running?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:39
latest I think,
just running npm install -s actionhero
Muhamed Krlić @l0oky Dec 14 2015 08:39
-s ?
donnyhardyanto @donnyhardyanto Dec 14 2015 08:40
--save
Muhamed Krlić @l0oky Dec 14 2015 08:40
oh
donnyhardyanto @donnyhardyanto Dec 14 2015 08:40
so install to local node_modules
in windows, if not using -s, we cannot generate
Muhamed Krlić @l0oky Dec 14 2015 08:40
yes then just npm install again
donnyhardyanto @donnyhardyanto Dec 14 2015 08:40
as per doc instruction
yes npm install and npm start fine
Muhamed Krlić @l0oky Dec 14 2015 08:41
yeah, you can npm install -g actionhero
then just actionhero start. That is assuming that you have same version in the project
node actionhero start --debug
nope
donnyhardyanto @donnyhardyanto Dec 14 2015 08:43
error
Muhamed Krlić @l0oky Dec 14 2015 08:43
that wouldn't work
donnyhardyanto @donnyhardyanto Dec 14 2015 08:43
Cannot find module
usually using this for debug
Muhamed Krlić @l0oky Dec 14 2015 08:44
@donnyhardyanto Are you running mingw32 or just plain cmd
donnyhardyanto @donnyhardyanto Dec 14 2015 08:45
plain cmd
Muhamed Krlić @l0oky Dec 14 2015 08:45
If you have git installed you also have git bash ( mingw32 env.)
open git bash and try running debug in git bash
the same way you did the first time
I moved to Linux I don't have to worry about that :)
that is anymore..
donnyhardyanto @donnyhardyanto Dec 14 2015 08:46
Error cannnot find modules
oh sorry i think it diffenet directory
Muhamed Krlić @l0oky Dec 14 2015 08:48
cd /c/../path to project
I liked git bash env. more than cmd :)
donnyhardyanto @donnyhardyanto Dec 14 2015 08:49
still the same
more info thought
Segmentation fault
Muhamed Krlić @l0oky Dec 14 2015 08:49
wat? :D
donnyhardyanto @donnyhardyanto Dec 14 2015 08:49
Couple days ago not like this
I usually use Intellij to manage/run/debug my nodejs/actionhero project for months
Only this day it fail
It can be work only if I disable websocket,
Muhamed Krlić @l0oky Dec 14 2015 08:50
Is It some Visual Studio thingy?
I use Atom editor
donnyhardyanto @donnyhardyanto Dec 14 2015 08:50
Something like that
Muhamed Krlić @l0oky Dec 14 2015 08:51
It has intellij too
donnyhardyanto @donnyhardyanto Dec 14 2015 08:51
But I think it is very confiniend
Muhamed Krlić @l0oky Dec 14 2015 08:51
yeah
donnyhardyanto @donnyhardyanto Dec 14 2015 08:51
*confinient
Intellij IDEA 15
Muhamed Krlić @l0oky Dec 14 2015 08:52
oh I mixed up intellisense
donnyhardyanto @donnyhardyanto Dec 14 2015 08:52
it is use also by Google for their AndroidStudio
it java based, but it is fast
Muhamed Krlić @l0oky Dec 14 2015 08:52
Yeah I used it on windows
donnyhardyanto @donnyhardyanto Dec 14 2015 08:52
Not like eclipse
Mac version is more speedly
Muhamed Krlić @l0oky Dec 14 2015 08:52
Eclipse is nasty
donnyhardyanto @donnyhardyanto Dec 14 2015 08:53
Yes, so slow
Muhamed Krlić @l0oky Dec 14 2015 08:53
=D
brb in 20 mins
donnyhardyanto @donnyhardyanto Dec 14 2015 08:53
prayer?
Muhamed Krlić @l0oky Dec 14 2015 08:53
yeah :D
donnyhardyanto @donnyhardyanto Dec 14 2015 08:53
Magrib?
Muhamed Krlić @l0oky Dec 14 2015 08:54
aham :D
Angelo Rodrigues @AngeloR Dec 14 2015 08:54
I’m a vim-er =( but I’ve been trying out c9.io for an AH project i’m working on and it seems pretty neat
Muhamed Krlić @l0oky Dec 14 2015 08:54
Isha*
donnyhardyanto @donnyhardyanto Dec 14 2015 08:54
Isya, ok :)
It middle of the night here
I think some think happen to one of dependency package
May be get updated and broken
Muhamed Krlić @l0oky Dec 14 2015 09:09
I'll do a test with a new project now
see If It brakes on my machine
@AngeloR c9.io a web IDE?
Can be pretty slow on some machines I tried it :/
Muhamed Krlić @l0oky Dec 14 2015 09:16
I use Atom for (almost) all my projects now
Open Source compared to Sublime
donnyhardyanto @donnyhardyanto Dec 14 2015 09:22
Can Atom do nodejs debugging?
Muhamed Krlić @l0oky Dec 14 2015 09:22
no
Atom is just an editor
a good one though
not IDE
I use node-inspector for debugging nodejs
Angelo Rodrigues @AngeloR Dec 14 2015 09:24
@l0oky yeah it is.. and yeah it can be =p I’ve only been playing with it a bit, but it has the nicest JS auto-complete I’ve seen.
Muhamed Krlić @l0oky Dec 14 2015 09:25
Yeah you can plug everything into it hah
I like the plain one though
and terminal
I just love the linux terminal
my dream app when I first installed linux
cmd, mingw32, cygwin was such a pain on windows
Angelo Rodrigues @AngeloR Dec 14 2015 09:26
haha yes =p tmux + vim is amazing
I feel like no matter what IDEs I end up trying I always end up back on those =p
Muhamed Krlić @l0oky Dec 14 2015 09:27
Exactly!
donnyhardyanto @donnyhardyanto Dec 14 2015 09:30
How the test going?
Muhamed Krlić @l0oky Dec 14 2015 09:31
Strange.
I don't get any output
No errors, nothing.
node ./node_modules/actionhero start --debug Right?
Muhamed Krlić @l0oky Dec 14 2015 09:37
node ./node_modules/.bin/actionhero start --debug
@donnyhardyanto try this node-debug ./node_modules/.bin/actionhero start --debug you won't get any output in terminal though.
donnyhardyanto @donnyhardyanto Dec 14 2015 09:40
I will test when I got back. I am looking for snack outside rightnow.
I am hungry
I am using node --debug .\node_modules\actionhero\bin\actionhero start
It the same?
Muhamed Krlić @l0oky Dec 14 2015 09:45
`node --debug ./node_modules/.bin/actionhero start
donnyhardyanto @donnyhardyanto Dec 14 2015 09:46
What is your output?
Muhamed Krlić @l0oky Dec 14 2015 09:46
Debugger starts normally
donnyhardyanto @donnyhardyanto Dec 14 2015 09:47
It not stopped?
Muhamed Krlić @l0oky Dec 14 2015 09:47
https://gist.github.com/l0oky/d4c655051c072df978cf
nope
donnyhardyanto @donnyhardyanto Dec 14 2015 09:48
It is normal
I am using \node_modules\actionhero\bin\actionhero
Muhamed Krlić @l0oky Dec 14 2015 09:48
It says debugger listening on port 5858
donnyhardyanto @donnyhardyanto Dec 14 2015 09:48
Yes your output is normal
I am using windows? You are using linux?
Muhamed Krlić @l0oky Dec 14 2015 09:49
Yes
You can get the same effect ( I guess ) If you run in git bash
donnyhardyanto @donnyhardyanto Dec 14 2015 09:57
>node --debug .\node_modules\.bin\actionhero start
Debugger listening on port 5858
C:\Users\Donny\Projects\Technocode\geofencemanager\node_modules\.bin\actionhero:4
case `uname` in
^^^^
SyntaxError: Unexpected token case
at exports.runInThisContext (vm.js:54:16)
at Module._compile (module.js:375:25)
at Object.Module._extensions..js (module.js:406:10)
at Module.load (module.js:345:32)
at Function.Module._load (module.js:302:12)
at Function.Module.runMain (module.js:431:10)
at startup (node.js:141:18)
at node.js:977:3
Muhamed Krlić @l0oky Dec 14 2015 09:57
pff
donnyhardyanto @donnyhardyanto Dec 14 2015 09:58
the same in git bash also
Muhamed Krlić @l0oky Dec 14 2015 09:58
Can you remake the whole project?
Generate actionhero, copy all your actions
etc..
donnyhardyanto @donnyhardyanto Dec 14 2015 09:59
It the same
I was trying that all day
Muhamed Krlić @l0oky Dec 14 2015 09:59
You tried it?
donnyhardyanto @donnyhardyanto Dec 14 2015 09:59
Yes
And now I am test with fresh vanilla actionhero
no action, no initializer, no change in config
as it is from actionhero generate
Still the same
What node version are you using? I am using 5.2
Muhamed Krlić @l0oky Dec 14 2015 10:00
can you go to file ./node_modules/bin/actionhero and copy whole file to http://gist.github.com?
Woooah
that's your problem right there
v0.10.29
your node has to be v0.10+
especially for v12 actionhero
donnyhardyanto @donnyhardyanto Dec 14 2015 10:01
I am, it is v12 I think
Nodejs decide to rename the version
Muhamed Krlić @l0oky Dec 14 2015 10:02
no update your node.js
donnyhardyanto @donnyhardyanto Dec 14 2015 10:03
It is the latest
Muhamed Krlić @l0oky Dec 14 2015 10:03
node -v // Should be higher then v0.10
npm -v // 2.1.8+
go to terminal type node -v
donnyhardyanto @donnyhardyanto Dec 14 2015 10:04
C:\Users\Donny\Projects\Technocode\geofencemanager>node -v
v5.2.0
C:\Users\Donny\Projects\Technocode\geofencemanager>npm -v
3.3.12
Muhamed Krlić @l0oky Dec 14 2015 10:04
Type this:
npm cache clean -f
npm install -g n
n stable
Probablly a windows release. I am confused right now
donnyhardyanto @donnyhardyanto Dec 14 2015 10:06
Previous Releases
io.js & Node.js
Releases 1.x through 3.x were called "io.js" as they were part of the io.js fork. As of Node.js 4.0.0 the former release lines of io.js converged with Node.js 0.12.x into unified Node.js releases.
So I am using v0.12+++
Muhamed Krlić @l0oky Dec 14 2015 10:07
right
Can you go to file ./node_modules/bin/actionhero and copy whole file to http://gist.github.com ?
it says something about line 4
donnyhardyanto @donnyhardyanto Dec 14 2015 10:08
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0..\actionhero\bin\actionhero" %
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0..\actionhero\bin\actionhero" %
)
Muhamed Krlić @l0oky Dec 14 2015 10:08
that's not .bin/actionhero
what did you just paste?
donnyhardyanto @donnyhardyanto Dec 14 2015 10:09
https://gist.github.com/donnyhardyanto/9115d79e4e934a0f8688
actionhero.cmd
it executed in windows
if in git bash, file is actionhero
I pasted in https://gist.github.com/donnyhardyanto/9115d79e4e934a0f8688
Muhamed Krlić @l0oky Dec 14 2015 10:11
Ok, go to your project. ./node_modules/bin/and then open file actionhero. Gist that
donnyhardyanto @donnyhardyanto Dec 14 2015 10:12
https://gist.github.com/donnyhardyanto/445f0b10fe44a167a068
Muhamed Krlić @l0oky Dec 14 2015 10:13
It should look something like this https://github.com/evantahler/actionhero/blob/master/bin/actionhero
donnyhardyanto @donnyhardyanto Dec 14 2015 10:13
oh, sorry it was .bin
https://gist.github.com/donnyhardyanto/d9bfcbdde46c2dd42617
Muhamed Krlić @l0oky Dec 14 2015 10:15
There is no any caseunamein
as It says in stack trace
donnyhardyanto @donnyhardyanto Dec 14 2015 10:16
it was .bin/actionhero in the git bash stacktrace
$ node --debug ./node_modules/actionhero/bin/actionhero start
Debugger listening on port 5858
info: actionhero >> start
2015-12-15 01:16:40 - notice: *** starting actionhero ***
2015-12-15 01:16:40 - warning: running with fakeredis
2015-12-15 01:16:40 - info: actionhero member 192.168.9.104 has joined the cluster
2015-12-15 01:16:40 - notice: pid: 6164
2015-12-15 01:16:40 - notice: server ID: 192.168.9.104
2015-12-15 01:16:40 - info: ensuring the existence of the chatRoom: defaultRoom
2015-12-15 01:16:40 - info: ensuring the existence of the chatRoom: anotherRoom
2015-12-15 01:16:40 - notice: starting server: web
2015-12-15 01:16:40 - notice: starting server: websocket
Segmentation fault
Muhamed Krlić @l0oky Dec 14 2015 10:17
remove the dot in .bin?
donnyhardyanto @donnyhardyanto Dec 14 2015 10:18
Segmentation fault
Muhamed Krlić @l0oky Dec 14 2015 10:18
I see
donnyhardyanto @donnyhardyanto Dec 14 2015 10:18
But if we disable websocket
Muhamed Krlić @l0oky Dec 14 2015 10:18
Looks like the binaries are not made for windows
donnyhardyanto @donnyhardyanto Dec 14 2015 10:19
It works
Muhamed Krlić @l0oky Dec 14 2015 10:19
you can't run ./node_modules/.bin/actionhero
donnyhardyanto @donnyhardyanto Dec 14 2015 10:19
use only ./node_modules/.bin/actionhero to generate
Muhamed Krlić @l0oky Dec 14 2015 10:20
Interesting. Post an issue on this
donnyhardyanto @donnyhardyanto Dec 14 2015 10:20
$ node --debug ./node_modules/actionhero/bin/actionhero start
Debugger listening on port 5858
info: actionhero >> start
2015-12-15 01:20:13 - notice: *** starting actionhero ***
2015-12-15 01:20:13 - warning: running with fakeredis
2015-12-15 01:20:13 - info: actionhero member 192.168.9.104 has joined the cluster
2015-12-15 01:20:13 - notice: pid: 8616
2015-12-15 01:20:13 - notice: server ID: 192.168.9.104
2015-12-15 01:20:13 - info: ensuring the existence of the chatRoom: defaultRoom
2015-12-15 01:20:13 - info: ensuring the existence of the chatRoom: anotherRoom
2015-12-15 01:20:13 - notice: starting server: web
2015-12-15 01:20:13 - notice: environment: development
2015-12-15 01:20:13 - notice: *** Server Started @ 2015-12-15 01:20:13 ***
Muhamed Krlić @l0oky Dec 14 2015 10:20
You did it?
donnyhardyanto @donnyhardyanto Dec 14 2015 10:21
See? It running well if websocket is disabled
Muhamed Krlić @l0oky Dec 14 2015 10:21
yeah
I'll try with websockets on sec
donnyhardyanto @donnyhardyanto Dec 14 2015 10:21
exports.default = {
servers: {
websocket: function(api){
return {
enabled: false,
on config/servers/websocket.js
Muhamed Krlić @l0oky Dec 14 2015 10:22
My websockets were enables
It works for me
I have no clue to whats causing this.
@donnyhardyanto How much RAM do you have available?
donnyhardyanto @donnyhardyanto Dec 14 2015 10:25
4.7 GB used of 7,9GB
59%
Muhamed Krlić @l0oky Dec 14 2015 10:26
Are you in any case using any other module?
donnyhardyanto @donnyhardyanto Dec 14 2015 10:26
no
Muhamed Krlić @l0oky Dec 14 2015 10:26
or just plain vanilla
ok
had to ask
donnyhardyanto @donnyhardyanto Dec 14 2015 10:26
just plain vanilla
Muhamed Krlić @l0oky Dec 14 2015 10:26
ok
try removing node_modules folder
and do npm install
donnyhardyanto @donnyhardyanto Dec 14 2015 10:27
ok
done
Muhamed Krlić @l0oky Dec 14 2015 10:30
Does it work now?
Try running debug command now
donnyhardyanto @donnyhardyanto Dec 14 2015 10:30
$ node --debug ./node_modules/actionhero/bin/actionhero start
Debugger listening on port 5858
info: actionhero >> start
2015-12-15 01:30:11 - notice: *** starting actionhero ***
2015-12-15 01:30:11 - warning: running with fakeredis
2015-12-15 01:30:11 - info: actionhero member 192.168.9.104 has joined the cluster
2015-12-15 01:30:11 - notice: pid: 9712
2015-12-15 01:30:11 - notice: server ID: 192.168.9.104
2015-12-15 01:30:11 - info: ensuring the existence of the chatRoom: defaultRoom
2015-12-15 01:30:11 - info: ensuring the existence of the chatRoom: anotherRoom
2015-12-15 01:30:11 - notice: starting server: web
2015-12-15 01:30:11 - notice: starting server: websocket
Segmentation fault
Still the same
Muhamed Krlić @l0oky Dec 14 2015 10:31
No idea. Post an issue on github https://github.com/evantahler/actionhero/issues probablly some incompatibility with windows.
oops markdown ftw
donnyhardyanto @donnyhardyanto Dec 14 2015 10:33
evantahler/actionhero#716
I have post the issue
I think I just disabled websocket for now and go forward with the work, while waiting issue to be investigated
Muhamed Krlić @l0oky Dec 14 2015 10:35
yeah
donnyhardyanto @donnyhardyanto Dec 14 2015 10:35
Many thanks @l0oky . Syukron
Muhamed Krlić @l0oky Dec 14 2015 10:35
:D
Evan Tahler @evantahler Dec 14 2015 11:30
@donnyhardyanto sadly, I think you are going to be out of luck for a while. I don't know anyone who has a wondows computer around who can help you (myself included)
Muhamed Krlić @l0oky Dec 14 2015 11:30
I do, but I can bearly help hah
Maybe I could do tests
Does travis ci have windows?
Evan Tahler @evantahler Dec 14 2015 11:31
on the plus side, I've added some docs for you to help clarify running 'server' vs 'worker' mode: evantahler/actionhero@970e9c9
(http://www.actionherojs.com/docs/#production-notes)
@l0oky not on the free plans for travis
Muhamed Krlić @l0oky Dec 14 2015 12:51
@evantahler Happy 2300th commit!
lol
Muhamed Krlić @l0oky Dec 14 2015 13:23
Probably an unrelated question but, when does code coverage raise? How do you test a uncovered statement?
You can't cover 100% of your code can you?
http://next.gitter.im/ <-- Don't click this, I warned you.
Muhamed Krlić @l0oky Dec 14 2015 13:29
There's a hidden rick roll there
Evan Tahler @evantahler Dec 14 2015 14:28
It's basically a linter. You can actually inspect the source of any function in JS. That includes line numbers. So when you run the test suite you can store all line numbers if you mess with function invocation.
Muhamed Krlić @l0oky Dec 14 2015 15:02
That is cool. I think I just had a 'good morning Columbo' moment
Colombo*
Evan Tahler @evantahler Dec 14 2015 17:45
It's certainly fancier than that... but that's how I understand the basics of it. I personally don't care about the small changes, but I keep it around as a reminder to test any new feature that shows up (the number would change dramatically). It hooks into travis to run atuomatically
Nathan @BoLaMN Dec 14 2015 19:23
@donnyhardyanto see of DEBUG=* gives any more details, I know ws has issues compiling on windows unless you have visual studio installed aswell
If*
NizarBlond @NizarBlond Dec 15 2015 01:03
@l0oky you promised that @evantahler will read my question, but he didn't (or just ignored it)
Muhamed Krlić @l0oky Dec 15 2015 04:03
@NizarBlond I didn't promise anything. That is very rude of you. Just saying. No need to put presure on anyone, especially in open source community. I recommend being patient.
@NizarBlond If you really care about your issue. Post it on github
Angelo Rodrigues @AngeloR Dec 15 2015 04:27
@NizarBlond what was your question?
Evan Tahler @evantahler Dec 15 2015 07:37
What's the question?
Chat is .... Chat. Messages get lost.
Muhamed Krlić @l0oky Dec 15 2015 08:28
Is it worth It to make plugins that are going to depend on project having some modules like sequelize ?
I am making a plugin that is going to depend on sequelize plugin.. but I cant just put it in my plugins package.json . Project user has to install it on his own.
So is this plugin-plugin dependency a good thing?
I will also have to worry about priority. So all plugins that my plugin is depending on needs to be lower priority..
Muhamed Krlić @l0oky Dec 15 2015 08:33
Any comment on this @evantahler ?
@evantahler I was thinking that this priority thing is a bit low level for actionhero user. Maybe adding something like action, plugin-to-plugin dependencies config will make things a lot easier. So actionhero will worry about priority.
Muhamed Krlić @l0oky Dec 15 2015 08:38
Automatically. Unless user wants It manualy set of course.
Evan Tahler @evantahler Dec 15 2015 08:45
You know, I've never tried nesting plugins!
Muhamed Krlić @l0oky Dec 15 2015 08:46
It's a real issue for me now. I mean I want reusable middlewares
Evan Tahler @evantahler Dec 15 2015 08:46
It might work already out of the box... or with a few simple tweaks anyway (the configLoader is pretty robust already, thanks to a lot of community help)
worst case, you'll have a few plugins in each project (ah-sequelize, l0oky-middleeare), which isn't too bad
but give it a shot! I have no idea what will happen :D
Muhamed Krlić @l0oky Dec 15 2015 08:48
hehe added a preinstall npm script to check project package.json for plugin dependencies.
Evan Tahler @evantahler Dec 15 2015 08:48
I'll bet folks like @neilstuartcraig would be super into nesting plugins
Muhamed Krlić @l0oky Dec 15 2015 08:48
No idea how to automatically manage priority though.
Developer will have to tweak them
Evan Tahler @evantahler Dec 15 2015 08:48
priority is meant to be explicit... sequilze (database connections) should always be a low number
things in your project that are middleware should always be a high number
Muhamed Krlić @l0oky Dec 15 2015 08:49
Yeah but like I mentioned above It's a bit low level for a developer. Automatic prority management would be awesome.
Evan Tahler @evantahler Dec 15 2015 08:49
and all of the init steps before the server accepts any connections
so you don't have to worry about that
I don't think I understand why you need it
as long as everything is connected before your first connection, what does it mater?
Muhamed Krlić @l0oky Dec 15 2015 08:50
I mean you're right. But what If someone decides to plug in my plugin into his, and priorities aren't set right.
You'll have to go to each file and edit it
Evan Tahler @evantahler Dec 15 2015 08:51
like... you can define a function in l0oky-middleeare that might use sequelize before the sequelize initilizer starts, but you won't actually invoke it until you have a connection... so it will be fine
Muhamed Krlić @l0oky Dec 15 2015 08:51
That's how it goes?
Then It's fine :)
Evan Tahler @evantahler Dec 15 2015 08:52
i mean, you could certainly have an initilizer like "ensure the root user is in the DB" which would crash without sequelize
Muhamed Krlić @l0oky Dec 15 2015 08:52
I remember my middleware not working because of priority number though.
Evan Tahler @evantahler Dec 15 2015 08:52
but that method would run in the start step, and sequelize would setup the connection in the init step
so that's fine too
remember the initializer sections as well
the only real convention is that "connections and core" are < 1000, and stuff for your application is > 1000
Muhamed Krlić @l0oky Dec 15 2015 08:53
I'll have to dive into these concepts a bit better.
Evan Tahler @evantahler Dec 15 2015 08:53
that tends to cover more or less anything
but let me know if you get stuck!
Muhamed Krlić @l0oky Dec 15 2015 08:53
kk thanks!
Evan Tahler @evantahler Dec 16 2015 07:50
so what are you all building?
Muhamed Krlić @l0oky Dec 16 2015 07:51
I am making a Access Control List Plugin :)
Muhamed Krlić @l0oky Dec 16 2015 07:56
It should handle all api keys and stuff. I am also figuring to what security strategy I should use. That can be a bit hard, that's why I am making a plugin.
Do It once, use it forever.
DefunctExodus @DefunctExodus Dec 16 2015 08:30
Lately working on integrating with some WiFi Cisco products , Not much fun.
Krishna Glick @krishnaglick Dec 16 2015 12:28
Is there something special I have to do to make data.params get populated with query params? Currently I have to do data.connection.rawConnecction.params.query['myQueryParam'] to get them.
Muhamed Krlić @l0oky Dec 16 2015 13:27
I think that's it. You use it for testing?
Evan Tahler @evantahler Dec 16 2015 17:20
Make sure your param is listed as an input to the action
Neil Craig @neilstuartcraig Dec 17 2015 07:08
@l0oky I made an ACL plugin a while ago. It's out of date versus action hero now and needs a refactor etc but I remember it being pretty fast and easy to use. Haven't looked at it in a while though tbh https://github.com/neilstuartcraig/TDPAHACLPlugin
danijeld @danijeld Dec 17 2015 08:25
Hello Evan, can you add to the "Action Inputs" section of the documentation what is the order of execution of required/formatter/validator/default properties?
danijeld @danijeld Dec 17 2015 08:55
@danijeld Also elaborate a bit on when/how "default" gets applied
Evan Tahler @evantahler Dec 17 2015 14:47
@danijeld sure thing! => evantahler/actionhero@774c34b
check docs/actions/inputs
http://www.actionherojs.com/docs/#inputs
Jacky @addedjacky Dec 18 2015 00:06
if post a file, the validator not effect , as the file is already upload to the server, TS @evantahler
NizarBlond @NizarBlond Dec 18 2015 03:09
I'm not sure if it is the right place to ask it, but I opened this issue evantahler/actionhero#721 as I am getting frustrated of running a very simple concept.
Greg Coonrod @gcoonrod Dec 18 2015 08:50
@evantahler I'm in the middle of an AH 10 to 12 upgrade. Wish me luck.
Evan Tahler @evantahler Dec 18 2015 10:37
@gcoonrod good luck!
@/all we've got a user, @NizarBlond who is having trouble understanding how configuration changes work to let actionhero run in "worker" mode or "server" mode. I've tried to answer him here a few times and now in this ticket: evantahler/actionhero#721. Can anyone here try to explain this another way for them?
If you can come up with a good example or metaphor, it would be great to add it to the documenation
I guess I've been assuming some basic BASH knowledge, which might not be the case for everyone
Thanks!
@addedjacky yep! that's correct. You can't validate a file :D
Greg Coonrod @gcoonrod Dec 18 2015 11:42
@evantahler We actually use the exact deployment @NizarBlond is asking about in ElasticBeanstalk.
Our web nodes have the scheduler off and no queues defined
Our worker nodes have no servers defined.
Well, that isn't 100% accurate. Our worker nodes do have web servers enabled but we route all web traffic to the web nodes.
Greg Coonrod @gcoonrod Dec 18 2015 12:11
Is the request object no longer in the data object in an action?
Evan Tahler @evantahler Dec 18 2015 13:24
Data.connection.originalConnection.req
Something like that
Chad Robinson @crrobinson14 Dec 18 2015 14:53
Folks, newbie-category question. Despite using AH for a year now I never seemed to learn the command-line mechanisms, and I know they exist. Is there a simple way to enqueue a task, with params, from a command line? I could write a simple interface to inject one but thought there was a mechanism for this already.
I found a grunt folder in node_modules/actionhero and it has a tasks.js set but nothing for normal tasks, just enqueueing periodic ones.
Evan Tahler @evantahler Dec 18 2015 15:06
There isn't! Open a GitHub issue, I'll make you one that accepts JSON params. That's a good idea!
Muhamed Krlić @l0oky Dec 19 2015 09:19
@neilstuartcraig How do you store your data in your acl plugin?
Neil Craig @neilstuartcraig Dec 19 2015 14:01
@l0oky not 100% sure what you mean but generally on the API object. Is that what you mean? The way I built it means each request just needs a small number of ifs, no db or redis lookups etc. It's pretty fast
Probably badly written in at least maintainability terms
Muhamed Krlić @l0oky Dec 19 2015 14:10
Oh ok, so everything is in memory.
I am making another type of access control though. Not really role based.
I am experimenting on another strategy called reason based access control
So to access my API you need to have a reason in a sense.
I'll explain everything once I finish this :)
Chad Robinson @crrobinson14 Dec 19 2015 14:27
@evantahler It's hard for me to submit a PR right now because I can't update my fork - I have an old legacy project I need to move off it. I'll do that soon.
In the meantime, doc update suggestion: action.inputs = { // a simple input // defaults assume required = false minimalInput: {} // a complex input multiplier: { required: true, validator: function(param, connection, actionTemplate){ if(param < 0){ return 'must be > 0' }else{ return true; } }, formatter: function(param, connection, actionTemplate){ return parseInt(param); }, default: function(param, connection, actionTemplate){ return 1; }, } };
Muhamed Krlić @l0oky Dec 19 2015 14:28
crrobinson14 you can put code instead of code :smile:
Chad Robinson @crrobinson14 Dec 19 2015 14:28
Oops, that pasted badly. That's from the docs on Actions -> Options. http://www.actionherojs.com/docs/#options parseInt(param) should be parseInt(param, 10) to avoid a common JS parsing mistake.
Values with leading 0s will be parsed as octal.
Muhamed Krlić @l0oky Dec 19 2015 14:29
```
LOL
Chad Robinson @crrobinson14 Dec 19 2015 14:29
I used that l00ky
```
Muhamed Krlić @l0oky Dec 19 2015 14:29
I see
Chad Robinson @crrobinson14 Dec 19 2015 14:29
Whatever. Three backticks.
Muhamed Krlić @l0oky Dec 19 2015 14:29
this is bugged haha
Chad Robinson @crrobinson14 Dec 19 2015 14:29
It's not quite like Slack. If you do it inline in a comment it does it like you wrote a single pair around it
Muhamed Krlić @l0oky Dec 19 2015 14:30
yeah
Chad Robinson @crrobinson14 Dec 19 2015 14:31
Also I might suggest that it's not clear frmo the docs what happens if you set required to true or false for required vs. optional params that also include default options
Muhamed Krlić @l0oky Dec 19 2015 14:32
@crrobinson14 Cool, There's a shortcut ctrl + / for compose mode
Chad Robinson @crrobinson14 Dec 19 2015 14:32
Nice.
Muhamed Krlić @l0oky Dec 19 2015 14:58
@evantahler How do I test my plugin with mocha? Do I make a test folder then copy that file into ah-project/test ?
Evan Tahler @evantahler Dec 19 2015 23:18
Here's an example plugin with a test suite. https://github.com/evantahler/ah-soap-plugin
Check
Checkout test/setup
Evan Tahler @evantahler Dec 20 2015 01:01
@crrobinson14 doc updates are also as easy as a pull request :D
Muhamed Krlić @l0oky Dec 20 2015 07:12
@evantahler integtation.js lol
It's funny cause It took me 10 minutes to realize it was spelled wrong. Didn't notice it before.
Evan Tahler @evantahler Dec 20 2015 08:36
Neither did I !
Muhamed Krlić @l0oky Dec 20 2015 08:42
@evantahler My plugin requires ah-sequelize-plugin to be loaded before it. How do I do this with the setup.js in ah-soap-plugin? I need to make another project to be able to test this..
I really need to get into this mocha testing routine.
Evan Tahler @evantahler Dec 20 2015 11:10
Add it as a dev dependancy. You'll. Probably have to modify the plugins path for your test Actionhero server.
Jacky @addedjacky Dec 21 2015 01:13
@evantahler THX, I rewrite the onPart function, everything sound great.
Nick Collins @ndcollins Dec 21 2015 09:00
What is the recommended way to have an action return a dynamically generated file? I have an action that is generating CSV data, but if I just return the CSV data in the response it returns it with all the characters escaped. The preferred way would be to actually return a CSV file that would start downloading
Evan Tahler @evantahler Dec 21 2015 11:33
not really an actionhero thing, but req is a stream, so you can pipe to it
so fs.read(csv).pipe(connection.rawConnection.res)
just be sure to set the response headers within your action and data.roRender=false so only the pipe'd data will be sent down
Muhamed Krlić @l0oky Dec 21 2015 12:04
@evantahler Is UDP transport supported?
I mean.. ofc not hehe
Because UDP has many standards.. I guess user would want his own standard since its User Datagram Protocol
Muhamed Krlić @l0oky Dec 21 2015 12:14
Technically I could make my own UDP server that does its stuff in /servers, right? Has access to the api object and all
Evan Tahler @evantahler Dec 21 2015 13:27
You got it!
I haven't seen any UDP servers yet. But that's why actuonhero (tries to be) easy to extend!
Check you the tcp/ socket server for an example.
Evan Tahler @evantahler Dec 21 2015 14:24
So we've got 986 GitHub stars.
Can I get 1K as a holiday present?
Muhamed Krlić @l0oky Dec 21 2015 14:24
lol
Muhamed Krlić @l0oky Dec 21 2015 14:31
14 to go
Muhamed Krlić @l0oky Dec 22 2015 06:05
10 to go
Chad Robinson @crrobinson14 Dec 23 2015 14:25
Starred.
Hey folks, I'm tracking down an issue in an initializer in Production in a cluster. It's (correctly) crashing the server but (annoyingly) not giving me a stack trace anywhere.
The docs say Other exceptions, perhaps occurring in an initializer, will not be caught. These are probably serious and should be investigated, and are allowed to crash the server.
Which is fair... But in startCluster mode it seems like STDOUT from child workers isn't logged anywhere.
This is a NodeJS exception - I've already found the bug and fixed it (accessing a function that doesn't exist) and I'm just trying to make sure things like this are logged in the future.
The STDOUT from the cluster master is pretty basic and just contains ESC[33malertESC[39m: worker 6019 (#2) has exited ESC[33malertESC[39m: worker 6010 (#1) has exited
The cluster master's own log file as configured by logging.js just has {"level":"alert","message":"worker 6019 (#2) has exited","timestamp":"2015-12-23T22:21:53.188Z"} {"level":"alert","message":"worker 6010 (#1) has exited","timestamp":"2015-12-23T22:21:53.191Z"}
Which matches it just in JSON format (which is how I have it configured)
The main log file for the children doesn't contain the stack trace.
Evan Tahler @evantahler Dec 23 2015 17:38
Yeah. Stdout for the cluster workers is suppressed. This needs to happen to fully detach the process. The only logs are Winston logs.
We could add something which passes stack traces back to the cluster master over ICP
That would be fancy!
Chad Robinson @crrobinson14 Dec 23 2015 18:30
I would settle for getting them into Papertrail - I have that working for other types of errors.
But I can't figure out where to trap them.
This seems to work: process.on('uncaughtException', function(exception) { api.log('uncaughtException: ' + exception.stack, 'error'); });
If I just chuck that in an initializer...
I hear it's deprecated but...
Evan Tahler @evantahler Dec 23 2015 22:55
Hmm... If its deprecated we shouldn't check it into core. Domains should be removed by the same logic...
Evan Tahler @evantahler Dec 24 2015 12:37
comment about domains here: evantahler/actionhero#722
@crrobinson14 I would rather do something like this:
if(!cluster.master){
process.on('uncaughtException', function(exception){
process.send('uncaughtException', exception);
api.shutdown();
});
}
and then on the cluster master, you would handle it
and log it
New Release! https://github.com/evantahler/actionhero/releases/tag/v12.4.0
Remove old utils
There were a number of old methods within the api.utils namespace which we are not using. Some of them were actually quite dangerous. They are gone now.
Removed methods:
api.utils.sqlDateTime(time)
api.utils.sqlDate(time)
api.utils.randomString(chars)
api.utils.sleepSync(seconds)
api.utils.randomArraySort(arr)
api.utils.inArray(haystack, needle)
by @evantahler via evantahler/actionhero#714
Task logging verbosity configuration options
allow for custom logging options for worker/task/scheduler options
defaults are now:
workerLogging : {
failure : 'error', // task failure
success : 'info', // task success
start : 'info',
end : 'info',
cleaning_worker : 'info',
poll : 'debug',
job : 'debug',
pause : 'debug',
internalError : 'error',
multiWorkerAction : 'debug'
},
// Logging levels of the task scheduler
schedulerLogging : {
start : 'info',
end : 'info',
poll : 'debug',
enqueue : 'debug',
reEnqueue : 'debug',
working_timestamp : 'debug',
transferred_job : 'debug'
},
by @dangerdespain via evantahler/actionhero#720
Fixed issue with websockets remaining open
by @ccapo via evantahler/actionhero#713
Documentation Updates
More information/examples about how to run actionhero in either serveror worker mode
Muhamed Krlić @l0oky Dec 28 2015 23:03
Doing dynamic stuff with routers would require api.routes.registerRoute(), this sounds cool.
Muhamed Krlić @l0oky Dec 28 2015 23:09
How do I migrate my actionhero project to a newer version of actionhero?
Can just npm install actionhero --save do for minor versions?
Santiago García Cabral @stylder Dec 29 2015 06:25
Hi everybody :D
My question is How can I show other variable en public page?
like this : http://postimg.org/image/yo34itftf/
Angelo Rodrigues @AngeloR Dec 29 2015 06:38
@l0oky depending on the complexity of my projects I end up just adding certain folders to git and shrinkwrapping the project. That way a clean clone can just npm install the latest version
Evan Tahler @evantahler Dec 29 2015 07:27
@stylder can you explain your question another way?
@l0oky yep, minor version changes should just work. Upgrade your package.json
Muhamed Krlić @l0oky Dec 29 2015 15:38
3 stars to go @evantahler !
Evan Tahler @evantahler Dec 29 2015 15:41
Everyone tweet :$
Muhamed Krlić @l0oky Dec 29 2015 15:54
1 to go? :D
Who's the lucky winner?
:D
Santiago García Cabral @stylder Dec 29 2015 22:12
In my public page where I show my actions.. I need show a variable like this http://i.imgur.com/297HZ8i.png?1
Evan Tahler @evantahler Dec 29 2015 22:32
So you want to define and then return arbitrary properties about your actions? Seems like a custom documentor I guess. You can also look at api.actions.actions and do whatever you want with that hash.
Santiago García Cabral @stylder Dec 30 2015 09:32
@evantahler Can you tell me how can do this with a example?
Evan Tahler @evantahler Dec 30 2015 13:52
sure:
here's the action
exports.myAction = {
name: 'myAction',
description: 'I return action data to clients. I also will return custom properties',
customActionProperty: 'abc123',
outputExample: {},
run: function(api, data, next){
data.response.actions = api.actions.actions;
next();
}
};
and here's the response:
> curl -v localhost:8080/api/myAction
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api/myAction HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Headers: Content-Type
< Access-Control-Allow-Methods: HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
< Access-Control-Allow-Origin: *
< X-Powered-By: actionhero API
< Content-Type: application/json; charset=utf-8
< Set-Cookie: sessionID=d52bc7973867566f2f9a9794f911debc8c9a63ec;path=/;expires=Wed, 30 Dec 2015 22:52:42 GMT;
< Content-Length: 5351
< Date: Wed, 30 Dec 2015 21:52:42 GMT
< Connection: keep-alive
<
{
"actions": {
"myAction": {
"1": {
"name": "myAction",
"description": "I return action data to clients. I also will return custom properties",
"customActionProperty": "abc123",
"outputExample": {},
"version": 1,
"inputs": {}
}
}
},
"serverInformation": {
"serverName": "actionhero API",
"apiVersion": "0.0.1",
"requestDuration": 1,
"currentTime": 1451512362362
},
"requesterInformation": {
"id": "d52bc7973867566f2f9a9794f911debc8c9a63ec-a9c00748-2a56-4eb8-8321-d442866b56ae",
"fingerprint": "d52bc7973867566f2f9a9794f911debc8c9a63ec",
"remoteIP": "127.0.0.1",
"receivedParams": {
"action": "myAction",
"apiVersion": 1
}
}
* Connection #0 to host localhost left intact
1001 GITHUB STARS!!!!! WE DID IT!!!!! IT'S A NEW YEARS MIRACLE!
haha
Santiago García Cabral @stylder Dec 31 2015 07:14
@evantahler Thanks you are the best !! this is the result http://i.imgur.com/fQY6zl2.png?1
Muhamed Krlić @l0oky Dec 31 2015 08:42
Hi @evantahler . Making that ah-steel-plugin that requires ah-sequelize-plugin nested I was talking about
test/setup.js sets project root to '/../node_modules/actionhero'. Which is kind of bad because I can't install ah-sequelize-plugin there, right?
Evan Tahler @evantahler Dec 31 2015 09:42
Why not? It's just a test dependancy.
Muhamed Krlić @l0oky Dec 31 2015 09:44
So I have to make a script that will copy dependency plugins in node_modules/actionhero? The fact that node_modules will not be commited to repo is a bit concerning then
It's not really just a test dependancy.. My plugin initializers will use ah-sequelize-plugin for example
I guess I'll just make another test project that will use this plugin just to test it? Feels like a hack..
Muhamed Krlić @l0oky Dec 31 2015 09:58
Yeah.. I guess I won't do that. It's a hack
Muhamed Krlić @l0oky Dec 31 2015 13:42
@evantahler Do you have any idea how nested plugins are going to be implemented?
I kind of want to prepare my project for that..
Evan Tahler @evantahler Dec 31 2015 14:06
I think the only changes needed are to the config loader.
Muhamed Krlić @l0oky Dec 31 2015 14:10
This message was deleted
Muhamed Krlić @l0oky Jan 01 06:38
@evantahler As you can see I have a test that requires ah-sequelize-plugin to be initiated before my plugin. But I dont really have clue how am I going to get this test passed. Shall I make a dummy project? It looks very unrealiable.
Muhamed Krlić @l0oky Jan 01 06:59
also where does process.env.ACTIONHERO_CONFIG path point to? actionhero project config ah-project/node_modules/actionhero/config or actionhero module config /ah-project/config ?
Muhamed Krlić @l0oky Jan 01 07:23
I think I got it. setup.serverConfigChanges.general.paths helps a lot If you want to use nested plugins!
Muhamed Krlić @l0oky Jan 01 08:00
@evantahler OK this is the best I could do to make nested plugins work in my plugin. Try cloning the repo and test it. This is my npm test output. As you can see I loaded the nested plugins but I couldn't make ah-sequelize-plugin load models from my plugin/models directory. It's also behaving unpredictably because nested plugins don't load config files from my plugins directory ( or do they ? ). This is confusing me a bit.
Evan Tahler @evantahler Jan 01 10:16
why do you have you action callback fire before the database model saves? https://github.com/l0oky/ah-steel-plugin/blob/master/actions/addReason.js#L60
Also, in this use case, I don't think the nesting you have is a good idea
the database connection should be "global", so if I choose to use sequelize, the main project should pull it in. Why would I seperate my "project" DB connection from my "auth" DB connection? Would you expect me to have 2 instances of sequelize?
Muhamed Krlić @l0oky Jan 01 11:32
@evantahler No that wasn't the plan. The user wouldn't use 2 db connection instances. The sqlite database in the plugin is used by the test server only.
so when I type npm test I don't want to rely on users db. I want to make use of a sqlite db file.
Also about that action.. yeah the plugin isn't finished yet. I started with solving the nested plugin issue.
Muhamed Krlić @l0oky Jan 01 11:53
I hope you see where I am getting at here :)
configLoader should load my configs, initializers or what not from my plugin after ah-sequelize-plugin and ah-jwtauth2-plugin. I made a test for that in test/integration.js using the current actionhero version I have. The part that isn't working is the ah-sequelize-plugin nested plugin itself. ( Apart from using the user db connection, it should have its own test connection in the case you want to run ah-steel-plugin tests - so dont get confused by the second sequelize connection I have defined in the config of the plugin ) In the integration.js test case, I wanted ah-sequelize-plugin to load the models in the test server. So I guess sequelize doesn't want to load models from my plugin I have to copy it?
OK I will copy it in the project root ( infact I have the scripts ready in ./scripts directory ) but the test project root is the actionhero module itself, so It's a bit concerning from that point of view.
Muhamed Krlić @l0oky Jan 01 12:02
This is the problematic line. But without it won't load my plugin.
and on the next line ( line 21 ) is where nested plugins are loaded into the test server.
All this you see is for testing purposes. The second db connection, the nested plugins to test if they're gonna load and to test the plugin itself ( because It is going to need all the plugins that were nested for testing in the real project.
Muhamed Krlić @l0oky Jan 01 12:31
@evantahler OK, after you read all that big text up there haha :D Here's what Travis-CI says. How could I get other tests passing?
donnyhardyanto @donnyhardyanto Jan 01 16:34
Hi, I am installing the actionhero for production servers. And the nodejs suddenly stop because ``node: ../deps/uv/src/unix/async.c:136: uv__async_io: Assertionn == sizeof(val)' failed.
It fail when there is 2 client access at same time or when I try to load test with 1000 requests sequentialy. My server is Debian, and I also test on Ubuntu and has same result. But Windows is OK. Has anyone has problem like that too?
Evan Tahler @evantahler Jan 01 18:23
Node version? And which server?
Muhamed Krlić @l0oky Jan 01 18:25
@donnyhardyanto Looks like something is wrong with your node.js
What do you mean 2 client access at the same time? How did you test that?
Muhamed Krlić @l0oky Jan 01 18:30
Or something else with the libuv
That exception looks nasty..
Muhamed Krlić @l0oky Jan 01 18:43
@evantahler You use monit? Is it good?
Evan Tahler @evantahler Jan 01 18:45
@donnyhardyanto I'm going to guess, totally randmoly, that your WS install has problems... try re-installing node-modules
@l0oky yep! love it
Muhamed Krlić @l0oky Jan 01 18:45
I am gonna trust you on this one
Evan Tahler @evantahler Jan 01 18:45
I even pay for m/monit https://mmonit.com
and it's cross platform
so I can use it ruby apps, databases, load balancers, etc
I try not to rely on something node specific
Muhamed Krlić @l0oky Jan 01 18:46
me too
I like node at the backend
ruby more of a web development
ror actually
@evantahler Hey um check out what I wrote a couple of hours ago. Can't wait for the nested plugins support.
Evan Tahler @evantahler Jan 01 18:49
it's going to be a few weeks until I get to look at it
Muhamed Krlić @l0oky Jan 01 18:49
I wish I knew more what configLoader does so I can contribute to it
Evan Tahler @evantahler Jan 01 18:50
it's all here https://github.com/evantahler/actionhero/blob/master/initializers/configLoader.js
and I disagree with your notion of it 'being unsafe' if its just for the test suite
Muhamed Krlić @l0oky Jan 01 18:50
Yeah, I'll read it :) Thanks
addConfigPath does adds the directory to be loaded
Muhamed Krlić @l0oky Jan 01 19:08
@evantahler So essentially what we need to do Is search the plugin package.json for dependencies and If It has any with ah-*-plugin pattern we compare that with project package.json. If project package.json doesn't have the 'nested' ah plugins installed and instantiated that the plugin needs we produce an error. Am I correct?
Evan Tahler @evantahler Jan 01 19:08
nope.
Muhamed Krlić @l0oky Jan 01 19:08
So in the sense we don't have any nested stuff
Evan Tahler @evantahler Jan 01 19:09
you are talking about evantahler/actionhero#727
maybe ... the issues are really mixed together
Muhamed Krlić @l0oky Jan 01 19:09
I think they are
because the project root is the one that should 'control' which plugins should be instantiated
That is - plugins should be predefined before used by any other plugins as 'nested'
@evantahler What did you really mean by nested plugins?
What kind of hierarchy are we talking about here? :)
donnyhardyanto @donnyhardyanto Jan 02 03:36
I was testing with node 5.3.0 and 4.2.4. server is ubuntu 14.04 and Debian 8
I am using web request only not websocket
And I am using fake redis. Can fake redis can be used with startCluster?
Muhamed Krlić @l0oky Jan 02 05:50
install real redis just in case
fake redis is not supposed to be used in production I guess.
Muhamed Krlić @l0oky Jan 02 09:10
@evantahler why is process.cwd() + '/../', used in your ah-soap-plugin/test/setup.js in serverConfigChanges.general.paths.plugin. To load the ah-soap-plugin itself? Could that accidentaly load another plugin?
@evantahler Also why does logger have lower priority than the configLoader? What If I need to log something from the configLoader? would It be acceptable to edit logger priority to 0 ?
I am going to try it
Muhamed Krlić @l0oky Jan 02 09:18
hmm interesting.. nothing is happening :)
Muhamed Krlić @l0oky Jan 02 09:43
@evantahler I think logger should initialize before the framework itself. So I can actually log everything.
Evan Tahler @evantahler Jan 02 10:10
Fakeredis would not cause that problem.
Muhamed Krlić @l0oky Jan 02 10:12
@evantahler I think that @donnyhardyanto -s issue has something to do with async
Evan Tahler @evantahler Jan 02 10:14
Nope.
Muhamed Krlić @l0oky Jan 02 10:15
Does node.js async module use libuv?
Evan Tahler @evantahler Jan 02 10:15
Async ( the package) is not a compiled one.
Async.c is in node,s core.
Muhamed Krlić @l0oky Jan 02 10:16
so it is compiled?
Evan Tahler @evantahler Jan 02 10:16
So the odds are very good that the error is coming from a compiled module. Or a bad node install itself.
Muhamed Krlić @l0oky Jan 02 10:17
Yeah @donnyhardyanto can you give us a project that reproduces the error? maybe a test of some sorts?
Muhamed Krlić @l0oky Jan 02 10:31
@evantahler I wanted to put this line api.log('Loaded plugin:', pluginPackageBase); right next to this line of code. Why is api.logger not initiated at that line of code? and How am I going to achieve this?
Evan Tahler @evantahler Jan 02 10:55
The config loader (and utils) are loaded before the logger, you are correct. That's because there are settings for the logger that the config loader needs to read! Like... should I log to a file, log to SNS, etc. You can see here that those 2 things are loaded first https://github.com/evantahler/actionhero/blob/master/actionhero.js#L98-L109
the config loader, when complete, should log nothing. When you are developing... try console.log?
Muhamed Krlić @l0oky Jan 02 10:58
Yeah, when I found out about that line of code in actionhero.js I was happy :D
I figured you loaded configLoader before anything else right there.
@evantahler Travis errored?
Synth Meat @synthmeat Jan 02 11:16
hey, is this mostly chan for actionhero devs or users are welcome too?
@synthmeat is not even a user yet
Muhamed Krlić @l0oky Jan 02 11:16
@synthmeat You've been here for a while.
I've been watching you :P
( you know there's a read by button on the right side )
Synth Meat @synthmeat Jan 02 11:17
as of few hours ago, yes. i'll idle here non-stop though now
Muhamed Krlić @l0oky Jan 02 11:18
For now there are no rules about devs/users chat rooms that I know of.
Synth Meat @synthmeat Jan 02 11:18
cool
Muhamed Krlić @l0oky Jan 02 11:18
everyone is welcome here hehe
Synth Meat @synthmeat Jan 02 11:19
been using https://github.com/NetEase/pomelo for 2-3 years now, and actionhero looks really really appealing
Muhamed Krlić @l0oky Jan 02 11:19
tell me about it
I was working with loopback and actionhero was more appealing for me..
still needs work though
Synth Meat @synthmeat Jan 02 11:20
yeah, i had backend for one game in loopback too, but switched that bit to... java :D
Muhamed Krlić @l0oky Jan 02 11:20
lol java.. so youre doing games? cool!
Synth Meat @synthmeat Jan 02 11:21
yeah, full time since 2008
i kind of thought actionhero will end up being used mostly for games. it's not?
Muhamed Krlić @l0oky Jan 02 11:23
No idea. Wasn't planning to use it for games :D
Synth Meat @synthmeat Jan 02 11:25
then what? apps? webapps?
Muhamed Krlić @l0oky Jan 02 11:25
This year was a though ride huh?
You can use it for anything you want!
Synth Meat @synthmeat Jan 02 11:26
:D
Muhamed Krlić @l0oky Jan 02 11:26
What I love about actionhero is the multitransport feature
Synth Meat @synthmeat Jan 02 11:26
yeah, it was a tough ride actually
Muhamed Krlić @l0oky Jan 02 11:26
you can use websockets, http(s), plain sockets
It's meant to be an API framework
Synth Meat @synthmeat Jan 02 11:27
pomelo has sockets, websockets, udp, nqtt
and whatever socket.io fallsback to after ws
also, it has hundreds of github issues, almost all of them in mandarin :D
Muhamed Krlić @l0oky Jan 02 11:28
hahaha
haha :D
Make an issue with the title ni hao do you speak english?
never heard of pomelo before though
Evan Tahler @evantahler Jan 02 11:29
Hey!
Synth Meat @synthmeat Jan 02 11:30
heya, author
Evan Tahler @evantahler Jan 02 11:30
Yeah, Actionhero was made at first for games!
But I think most folks use it for WS + HTTP these days.
Muhamed Krlić @l0oky Jan 02 11:30
Interesting
Evan Tahler @evantahler Jan 02 11:31
I also don't know a word of mandarin, and only 3 curse words in Cantonese
Muhamed Krlić @l0oky Jan 02 11:31
hehe
Evan Tahler @evantahler Jan 02 11:32
But yeah, this chat is for everyone!
Synth Meat @synthmeat Jan 02 11:32
from what i saw, it's pretty much what i came up with my implementations within pomelo framework. redis ephemeral data, actions vs tasks (i called them jobs), etc. plus sane configs
would've really like that i had this 2 years ago
Muhamed Krlić @l0oky Jan 02 11:32
@evantahler Travis-CI errored and scared me a little bit. I thought I broke something lol
Synth Meat @synthmeat Jan 02 11:33
is there .jscsrc or .jshintrc lying somewhere for actionhero codebase?
s/or/and
Evan Tahler @evantahler Jan 02 11:33
Yeah, it errors every now and then. I'll just run them again.
https://github.com/evantahler/actionhero/blob/master/.jshintrc
Muhamed Krlić @l0oky Jan 02 11:34
would've really like that i had this 2 years ago
That's how I've felt when I first came across actionhero, mine was 3 months though
Evan Tahler @evantahler Jan 02 11:35
I guess I shouldn't point out I think this is now a 4 year old project...
But then again, I'm terrible at SEO
Synth Meat @synthmeat Jan 02 11:35
i actively searched for prexisting solutions and didn't see it
i barely stumbled upon it the other day too
Muhamed Krlić @l0oky Jan 02 11:36
Yeah! I think I saw this actionhero coat logo a few years back though
Synth Meat @synthmeat Jan 02 11:36
(pomelo is 4 years old too)
Muhamed Krlić @l0oky Jan 02 11:36
I didn't even bother checking it out
( I think )
probably dejavu lol
Evan Tahler @evantahler Jan 02 11:37
If y'all have any good evangelism suggestions, please shoot them my way!
Synth Meat @synthmeat Jan 02 11:37
evantahler: get it on awesome lists
Muhamed Krlić @l0oky Jan 02 11:37
Those freelance blogs
Synth Meat @synthmeat Jan 02 11:38
awesome js, awesome node, awesome game, ...
https://github.com/sindresorhus/awesome
Muhamed Krlić @l0oky Jan 02 11:38
that looks awesome.js
Synth Meat @synthmeat Jan 02 11:38
:)
Evan Tahler @evantahler Jan 02 11:39
Huh!
@l0oky can you do that? I'm at the car wash :)
Muhamed Krlić @l0oky Jan 02 11:40
sure why not
@evantahler The downside is you'll have to put this badge on your readme.md
hahaha
Synth Meat @synthmeat Jan 02 11:42
awesome :)
Muhamed Krlić @l0oky Jan 02 11:42
purple badge
aweeeseomme
yeah hipster actionhero
ohh wait
@evantahler Dude, the awesome list isn't just a list. It's a book collection.
Synth Meat @synthmeat Jan 02 11:45
yeah, that thing is huge
awesome is list of lists really. and you can shove actionhero to many of those lists
js, node & game are just the most obvious ones
Muhamed Krlić @l0oky Jan 02 11:47
@synthmeat It's a start... Hhahaha
Synth Meat @synthmeat Jan 02 11:47
:)
@synthmeat goes to watch sherlock
Muhamed Krlić @l0oky Jan 02 11:48
New season is out?
Synth Meat @synthmeat Jan 02 11:54
christmas special, feature-length
Muhamed Krlić @l0oky Jan 02 11:54
Oooh that one
@synthmeat waits for it :)
Synth Meat @synthmeat Jan 02 11:55
anyways, anyone running it in production? any showcases?
Synth Meat @synthmeat Jan 02 12:00
@l0oky, ei bolan, ja iz imotskog! :)
Muhamed Krlić @l0oky Jan 02 12:01
hahaha
super znaci balkanac
Synth Meat @synthmeat Jan 02 12:01
da, da
Muhamed Krlić @l0oky Jan 02 12:01
ko bi rekao :D
svijet je mali hehe
Synth Meat @synthmeat Jan 02 12:02
otkud iz bosne?
Muhamed Krlić @l0oky Jan 02 12:02
Sarajevo
digla se magla sad ce snijeg haha
Synth Meat @synthmeat Jan 02 12:02
je, mene kosti bole vec dva dana
Muhamed Krlić @l0oky Jan 02 12:04
Imotska krajina to je dole kod mora, jugo-zapad? :D
Synth Meat @synthmeat Jan 02 12:04
je, ali sam sam u splitu/zagrebu uglavnom
Muhamed Krlić @l0oky Jan 02 12:05
aha
onda mora da si cuo za hub387 a?
Synth Meat @synthmeat Jan 02 12:05
ne, ja samo od kuce radim :)
Muhamed Krlić @l0oky Jan 02 12:05
startup ekipa dolazila u splitu bio hackathon svasta nes
haha isto
Synth Meat @synthmeat Jan 02 12:12
later :)
Muhamed Krlić @l0oky Jan 02 12:12
haj :D drago mi je :)
Muhamed Krlić @l0oky Jan 02 12:51
@evantahler Were there any actionhero.js conferences?
Muhamed Krlić @l0oky Jan 02 12:57
@evantahler This is what we will add to awesome list. Needs work.
But first I want you to take a look at this, see what you like/don't like :)
donnyhardyanto @donnyhardyanto Jan 02 13:16
@l0oky I will prepare minimum test code.
Muhamed Krlić @l0oky Jan 02 13:16
@donnyhardyanto Yeah, thanks. I don't want that error poping up on my production servers. :)
donnyhardyanto @donnyhardyanto Jan 02 13:23
And I began to think this is linux implementation of node error. Windows fine.
Muhamed Krlić @l0oky Jan 02 13:24
I am running Debian 8
donnyhardyanto @donnyhardyanto Jan 02 13:25
And also when I use actionhero sendfile from action, the error is not showup. I tested with 4 concurent threads, each doing 1000 request sequentially.
Muhamed Krlić @l0oky Jan 03 04:04
@evantahler Does ah-ratelimit-plugin work for actionhero 12+ ?
making that awesome list requires a bit of research :)
Evan Tahler @evantahler Jan 03 13:05
no clue. ask the author!
open a GitHub issue... that's usually the best way
Muhamed Krlić @l0oky Jan 03 13:06
oh yeah sorry, heh..
You have a lot of ah-plugins :)
@evantahler What do you think? https://github.com/l0oky/awesome-actionhero you like it?
please contribute this can make actionhero popular
Evan Tahler @evantahler Jan 03 13:09
great start!
why is the logo blue?
Muhamed Krlić @l0oky Jan 03 13:09
thanks
Evan Tahler @evantahler Jan 03 13:09
there's a list of plugins here http://www.actionherojs.com/docs/#example-plugin
Muhamed Krlić @l0oky Jan 03 13:10
no idea.. maybe to differentiate the real actionhero repo from this repo. It looked kinda the same with the red coat and all
Want me to change it?
It's still not finished
Was looking for the feedback
Evan Tahler @evantahler Jan 03 13:10
yeah, please use the normal one so folks recognize it
Muhamed Krlić @l0oky Jan 03 13:10
kk
Evan Tahler @evantahler Jan 03 13:11
here's some example projects: https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf, https://github.com/evantahler/earlyagain
and the tutorial: https://github.com/evantahler/actionhero-tutorial
Muhamed Krlić @l0oky Jan 03 13:11
awesome
Patrick Ahlgrimm @pahlgrimm Jan 05 04:43
@evantahler Hi Evan, I was looking for a good/suitable api framework and actionhero seems to be the solution for me
I doo habe 3 questions:
In some posts I read the actionhero is (just) maintained by yourself which is then conencted to a warning "on man show, be careful!" Any words about that? I am a 1.5 it service provider and know such thoughts also
If I get it right I put all my middleware into the initializers folder, right?
I wanna use Auth0 service and they suggest using express-jwt which would be pretty useless in ah. So my idea is to rewrite it to use the data object instead of express' req and res. Can I just append .user to the data object to acces it like data.user or where do put that user object in my middleware?
Thanks in advance!!!
Muhamed Krlić @l0oky Jan 05 10:17
@pahlgrimm that's a 1. big question ( joke ) :D
@pahlgrimm actionhero has been here for about 4 years by now, and is just starting to catch up right now. We need more core developers into this one. ( I hope to become one :) ) So the best way is to ask away I guess hehe.
Muhamed Krlić @l0oky Jan 05 10:24
@pahlgrimm For the second question, yes. You define middleware as an intializer. Here's an example
Muhamed Krlić @l0oky Jan 05 10:29
For the third question. You can make plugins for actionhero pretty much the way you want. We want to make it even more flexible by introducing nested plugins or plugin auto-registration...
Evan Tahler @evantahler Jan 05 13:30
Nice answers @l0oky !
Muhamed Krlić @l0oky Jan 05 13:46
yey, I am making progress :)
thanks
Patrick Ahlgrimm @pahlgrimm Jan 05 14:44
Yeah, those answers were helpful :smile:
I assume that data.connection.rawconnection.req is the request object from node, right? I wanna access the header values of the request.
Muhamed Krlić @l0oky Jan 05 14:48
yes
actually wait
yeah its in the data.connection
if you want parameters in action you can do data.connection.params
Here's an example action This is not really an example action ( because it doesn't explain stuff ) but you can see how to validate parameters and format them
( It's from my unfinished plugin, so It doesn't do anything :) )
Patrick Ahlgrimm @pahlgrimm Jan 05 14:52
I wanna access HTTP headers. For example look for a header "authorization" and read the value (JWT)
Muhamed Krlić @l0oky Jan 05 14:53
look at this plugin it does exactly what you want https://github.com/ifavo/ah-jwtauth-plugin/
https://github.com/ifavo/ah-jwtauth-plugin/blob/master/initializers/jwtauth_middleware.js#L25
There that line
Patrick Ahlgrimm @pahlgrimm Jan 05 14:55
YES! I was googling for two days now and didn't find that! Thanks!!!!
I actually wanna use Auth0 services!
Muhamed Krlić @l0oky Jan 05 14:55
that plugin is actually very useful
the original author is not mantaining this jwtauth plugin so the one done by ifavo is an up to date version
( i contributed to that plugin a bit too :) )
Patrick Ahlgrimm @pahlgrimm Jan 05 14:57
You're my hero! :+1:
Muhamed Krlić @l0oky Jan 05 14:57
actionhero :D
Patrick Ahlgrimm @pahlgrimm Jan 05 15:05
How is it possible to use some kind of nested actions? For example: /ticket/:id/createemail with form-encoded or json-data?
Patrick Ahlgrimm @pahlgrimm Jan 05 15:26
Okay, I think I get it: data is always expected to be a JSON-Object right? So if create an action ticket with an export.createmail I can just call it /ticket/createmail with all data in the json?
Evan Tahler @evantahler Jan 05 17:37
there are also custom routes you can make
http://www.actionherojs.com/docs/#routes
VMRC91 @VMRC91 Jan 07 06:17
Hello, how i can make querys to sql with actionhero, someone can send me a link or something like that please
Greg Coonrod @gcoonrod Jan 07 06:48
Has anyone implemented custom logging levels? I'm seeing an issue where using custom levels causes my winston transports to ignore the level I set for the transport. e.g. I set the transport to 'info' but I see debug levels in the logs.
Evan Tahler @evantahler Jan 07 07:39
@VMRC91
@VMRC91 check out sequelize
Muhamed Krlić @l0oky Jan 07 07:42
@VMRC91 Check this out.
You'll find ah-sequelize-plugin there
Muhamed Krlić @l0oky Jan 07 09:56
@gcoonrod Could you send me some code that recreates the issue? : )
peterkingsbury @peterkingsbury Jan 07 10:42
Great work on adding logging levels to tasks. I was just thinking today about submitting a feature request to programmatically disable job completion notifications
Greg Coonrod @gcoonrod Jan 07 10:53
@l0oky @evantahler https://gist.github.com/gcoonrod/c49fce9d68b382cb76f4
Here is a simplified version of the logging config i'm using.
Evan Tahler @evantahler Jan 07 12:54
that looks right to me here's where it's applied
https://github.com/evantahler/actionhero/blob/master/initializers/logger.js#L19-L27
Greg Coonrod @gcoonrod Jan 07 12:54
Yup, I
I've been staring at that code for a while now
Evan Tahler @evantahler Jan 07 12:54
can you expirment with trying ways to init winston within actionhero? Perhaps they want us to init with the colors now, and not apply them afterwords
Greg Coonrod @gcoonrod Jan 07 12:54
I'm suspecting its an issue with winston
Evan Tahler @evantahler Jan 07 12:55
and you've confirmed that your config is working right, yeah? api.config.logger.levels isn't null?
Greg Coonrod @gcoonrod Jan 07 12:55
correct
Evan Tahler @evantahler Jan 07 12:55
hmmmmm
Greg Coonrod @gcoonrod Jan 07 12:55
the levels get created correctly
it just ignores the level filter on the transport
Evan Tahler @evantahler Jan 07 12:55
try moving https://github.com/evantahler/actionhero/blob/master/initializers/logger.js#L17 into the if() block, and making a new logger explicitly if they custom stuff is set
silly winston
Greg Coonrod @gcoonrod Jan 07 12:57
https://gist.github.com/gcoonrod/fc25881512fd177c3c2f
based on the testing in that gist i suspect that runtime changes to the logging levels causes problems
if i move the creation of the logger into the if block i can add the levels as a value in the options hash. Which will remove the need for runtime changes to the logger.
I suspect that I can move the color add to before the creation of the logger as well, since that is applied to winston directly.
Evan Tahler @evantahler Jan 07 16:59
makes sense
send in a PR, that makes sense to me
thanks for looking into it!
Angelo Rodrigues @AngeloR Jan 08 13:49
does AH let me supply mocked objects in my tests? For example, I do by db connection pool setup in a initializer. Instead of utilizing this when running the test, I want to inject my own mock object so that I’m not writing to the database.
Greg Coonrod @gcoonrod Jan 08 13:51
@AngeloR take a look at sinon.js
Angelo Rodrigues @AngeloR Jan 08 13:54
cool, thanks
I’ll have to play around with this this evening
Evan Tahler @evantahler Jan 08 16:03
I've used this for test fixtures https://github.com/domasx2/sequelize-fixtures
remember that actionhero doesn't have an ORM, or care about your data... so this is all in user land :D
Patrick Ahlgrimm @pahlgrimm Jan 08 16:05
@evantahler One of the reason I chose actionhero is the fact that there is NO ORM! :smile:
Evan Tahler @evantahler Jan 08 16:05
indeed!
Angelo Rodrigues @AngeloR Jan 08 16:06
oh yeah, I'm good with that. I was just trying to figure out how to inject my mocks into the api object that's passed to the run methods in routes
Evan Tahler @evantahler Jan 08 16:06
ahh, got it.
Muhamed Krlić @l0oky Jan 09 06:11
OK people, lets make this framework popular! sindresorhus/awesome#474 We need more plugins, more videos, more blogs, If not update your existing content. This framework could get popular fast. And that means more features and better support.
Muhamed Krlić @l0oky Jan 09 06:17
Lets show people what actionhero is! We have a chance at this, we just need a bit more content. Putting actionhero on awesome-list will open doors to a bigger community and actionhero could develop exponentially!
Evan Tahler @evantahler Jan 09 09:26
@l0oky saying that message in this room will have fairly poor results... folks here already care. Tweet that message, put it on FB and snapchat... buy some google ads against it. That will help a lot more
Muhamed Krlić @l0oky Jan 09 09:27
I'll do what's in my power :)
Evan Tahler @evantahler Jan 09 09:27
:D
Evan Tahler @evantahler Jan 09 10:23
New version out!
https://github.com/evantahler/actionhero/releases/tag/v12.4.1
This message was deleted
FORWARD WARNING: This is likely to be the last update to actionhero which supports node versions less than 4.0.0.
Many of the packages we depend on are moving to target the LTS release of 4.2.2 as their minimum build. Actionhero will be following suit. Version 13.0.0 will have a target of node >=4.0.0
Release Notes
matchTrailingPathParts in router
Enables a new option, matchTrailingPathParts which you can enable in the router to match combination paths:
post: [
// yes match: site.com/api/123
// no match: site.com/api/123/admin
{ path: '/login/:userId(/.*/)', action: 'login' }
],
post: [
// yes match: site.com/api/123
// yes match: site.com/api/123/admin
{ path: '/login/:userId(/.*/)', action: 'login', matchTrailingPathParts: true }
],
This also enables "catch all" routes, like:
get: [
{ path: ':path(/.*/)', action: 'catchAll', matchTrailingPathParts: true }
],
If you have a route with multiple variables defined and matchTrailingPathParts is true, only the final segment will match the trailing sections:
get: [
// the route site.com/users/123/should/do/a/thing would become {userId: 123, path: '/should/do/a/thing'}
{ path: '/users/:userId/:path(/.*/)', action: 'catchAll', matchTrailingPathParts: true }
],
by @evantahler via evantahler/actionhero#728
Misc Updates
General formatting changes to make more files pass the JS linter
by @evantahler via evantahler/actionhero#723
Formatting help
by @l0oky via evantahler/actionhero#730
Documentation link update
by @l0oky via evantahler/actionhero#732
Dependency update
by @evantahler via evantahler/actionhero#733
@/all PLEASE NOTE: FORWARD WARNING: This is likely to be the last update to actionhero which supports node versions less than 4.0.0.
Many of the packages we depend on are moving to target the LTS release of 4.2.2 as their minimum build. Actionhero will be following suit. Version 13.0.0 will have a target of node >=4.0.0
Greg Coonrod @gcoonrod Jan 09 10:42
@evantahler figured out the custom logging issue. Dumb error, I had ordered the logging levels backwards.
Muhamed Krlić @l0oky Jan 09 12:03
@gcoonrod haha :) where?
v13 is on the horizon, :)
Synth Meat @synthmeat Jan 09 12:35
i'm going to have to fight really hard to get it to run with just "node whatever.js", aren't i?
Evan Tahler @evantahler Jan 09 12:42
@gcoonrod ha!
@synthmeat what do you mean?
You want to write your own container? Super easy: http://www.actionherojs.com/docs/#programatic-use-of-actionhero
@synthmeat reads up
Synth Meat @synthmeat Jan 09 12:46
i've burnt myself twice with monolithic, configuration-heavy things
never again
that's rails legacy
@synthmeat hated rails too
Muhamed Krlić @l0oky Jan 09 13:21
I am thinking of making actionheroPrototype shorter. I don't know looks too long. Maybe ahPrototype ? What do you think guys? Just a cosmetic touch nothing serious..
Synth Meat @synthmeat Jan 09 13:26
how do players on different cluster nodes communicate?
or, can players on different cluster nodes be in the same room?
Muhamed Krlić @l0oky Jan 09 13:27
I think there is actionhero client made just for that job. I am not sure. I didn't touch redis stuff yet.
that's how It's called actionhero-client-ish
Maybe? I don't think I am right..
Synth Meat @synthmeat Jan 09 13:29
the last framework i used abstracted client's "session" data
so you'd push into it, and it'd magically appear on every server
ok, i guess what i wanna know is - how do cluster nodes communicate (ignore the client)
is there any point of integration beyond them sharing the same dbs?
Synth Meat @synthmeat Jan 09 13:46
OK!
there's more to actionhero than horrible code style
(quite literally code style. as in, indentations and stuff )
@synthmeat goes to fork it
Evan Tahler @evantahler Jan 09 14:23
@l0oky absolutely do not abbreviate anything internal.
That sort of crosses the line into user-facing, so... Maybe. But never "ah"
@synthmeat I think you are looking for the docs on 'chat'
Which doesn't imply he said she said. But message passing
Synth Meat @synthmeat Jan 10 01:24
where is this 'next' from? https://github.com/evantahler/actionhero/blob/master/config/logger.js#L24
Muhamed Krlić @l0oky Jan 10 03:27
@evantahler I didn't like ah either
Muhamed Krlić @l0oky Jan 10 03:36
@evantahler Chat sounds quite like person to person chat. Maybe Message Queue ( MQ ) would be the better word?
I was confused at the beginning what is actionhero chat really..
Muhamed Krlić @l0oky Jan 10 04:02
@evantahler Which linter are you using? I am using Atom + Linter. It didn't work with JSHint because the file was named .jshintrc and my linter requires filename to be .jshint hah
Is it possible to rename .jshintrc to .jshint ? Will it break someones linter?
Muhamed Krlić @l0oky Jan 10 04:19
@evantahler There are 720+ missing semicolons haha shall I do a PR on this?
I also found you using eval in 2 places I guess that's what we need to fix for v13
Evan Tahler @evantahler Jan 10 08:15
@l0oky if you can solve those eval calls, I would be the happiest!
you can't cheat and use JSON.parse... it's just as bad :D
@l0oky that ; PR is awesome
full on OCD!
Muhamed Krlić @l0oky Jan 10 08:18
hahah
Evan Tahler @evantahler Jan 10 08:18
I have no idea what linter I was using when this project stated. It was before atom or sublime were out... so who knows
probably nothing :D
Muhamed Krlić @l0oky Jan 10 08:21
I was using atom + linter package + linter-jshint package
jshint doesn't work with file name .jshintrc though
i had to rename mine to just .jshint
Muhamed Krlić @l0oky Jan 10 08:34
@evantahler You know.. subscriptionHandlers sounds much like event handling
Muhamed Krlić @l0oky Jan 10 08:40
var events = require('events');
var eventEmitter = new events.EventEmitter();
var ringBell = function ringBell()
{
console.log('ring ring ring');
}
eventEmitter.on('ringBell', ringBell);
if(message.method === 'ringBell'){
eventEmitter.emit(message.method);
}
Something like this could work as an eval() workaround?
This has to have defined methods though
I am not sure what subscriptionHandlers.do does really btw
Synth Meat @synthmeat Jan 10 08:46
evantahler: i'm a bit OCD and i'd like to cut out a full .jshintrc as well as .jscsrc for this, while respecting fully existing code style. would that be acceptable?
undoubtedly, that'll have a lot of "junk" changes in repo, but v13 might be opportunity for that. dunno
Evan Tahler @evantahler Jan 10 09:00
@l0oky subscriptionHandlers is event handling, for redis, yes
What's the question?
Muhamed Krlić @l0oky Jan 10 09:00
What is subscriptionHandlers.do meant for?
Evan Tahler @evantahler Jan 10 09:01
http://www.actionherojs.com/docs/#rpc
Muhamed Krlić @l0oky Jan 10 09:01
so its under rpc ok thanks
Evan Tahler @evantahler Jan 10 09:02
@synthmeat yeah, go for it! The style here does need a fair amount of <3
@synthmeat are you working on pkg in node-redis, or want me to take a crack at it?
Synth Meat @synthmeat Jan 10 09:03
evantahler: i can fork and do it, no problem
Muhamed Krlić @l0oky Jan 10 09:04
@evantahler He is doing something :) synthmeat/actionhero@021ba51
Evan Tahler @evantahler Jan 10 09:04
I'm talking about the test failures here taskrabbit/node-resque#113
I just became very excited to learn that gitter has a CLI app https://github.com/RodrigoEspinosa/gitter-cli
Muhamed Krlić @l0oky Jan 10 09:05
what?!
cool
Synth Meat @synthmeat Jan 10 09:06
i use gitter from within weechat :)
Evan Tahler @evantahler Jan 10 09:06
third party... little node REPL app
Synth Meat @synthmeat Jan 10 09:06
anyways, checking on the travis fails, a moment
Evan Tahler @evantahler Jan 10 09:06
ooooooohhhhh!
@evantahler checks out weechat
Synth Meat @synthmeat Jan 10 09:07
i have slack there, twitch too
Muhamed Krlić @l0oky Jan 10 09:07
@evantahler Good morning colombo!
best IRC chat client ever
@synthmeat goes to check on node-resque issue
Evan Tahler @evantahler Jan 10 09:21
I personally have always loved adium (i'm on OSX) but it doesn't handle rooms too well which is a no-go for gitter, hipchat, or slack
Synth Meat @synthmeat Jan 10 09:21
evantahler: it shows that i've been working solo for many years now, ei? :)
Evan Tahler @evantahler Jan 10 09:21
haha
all good
Synth Meat @synthmeat Jan 10 09:22
i'm not versed in pull requests. i can edit them?
Evan Tahler @evantahler Jan 10 09:22
yep!
just change and push your branch
and it will update
a PR is just a link that says you want some tag (your_fork/your_branch) to go into another tag (my_fork/my_branch). if those tags move, then the PR updated
Synth Meat @synthmeat Jan 10 09:23
ah, so its pulling whatever's the head on my fork in that particular branch?
simple enough
Evan Tahler @evantahler Jan 10 09:23
si.
you can also do a PR from a specific git sha or tag... but that's fancy
I'm curious, where are you folks in the world? I'm in the USA and I'm living the dream: sipping tea by the fire and merging PRs
its 9am here
Synth Meat @synthmeat Jan 10 09:25
evantahler: croatia, bordering l0oky's country
Evan Tahler @evantahler Jan 10 09:25
neat!
Synth Meat @synthmeat Jan 10 09:25
evantahler: node-resque is now passing on me locally with FAKEREDIS=true, but not with false. any guideline on setting up testing environment?
Evan Tahler @evantahler Jan 10 09:25
you both have excellent english by the way.
Synth Meat @synthmeat Jan 10 09:26
it's because they don't dub our tv
poland, italy, and many others dub, and they suck at english
Evan Tahler @evantahler Jan 10 09:26
that... makes a fascinating amount of sense!
Muhamed Krlić @l0oky Jan 10 09:26
haha
Evan Tahler @evantahler Jan 10 09:26
for node-resque, all you should need is redis running localay
Synth Meat @synthmeat Jan 10 09:26
evantahler: yeah, i got laid once in italy because of that statement's wit :)
Evan Tahler @evantahler Jan 10 09:27
lol
Synth Meat @synthmeat Jan 10 09:27
evantahler: we talking node-redis or node-resque?
Evan Tahler @evantahler Jan 10 09:27
whops, node-resque
let me know if you need help installing/running it
Synth Meat @synthmeat Jan 10 09:27
no, i'm fine with redis
just not with tests in general
we game people don't like tests much
Muhamed Krlić @l0oky Jan 10 09:28
I have to disagree about that :D
Evan Tahler @evantahler Jan 10 09:28
I've seen some amazing games tests (back when I worked in games). some of the AI pathfinding tests were the fanciest things I've ever seen
Synth Meat @synthmeat Jan 10 09:29
yeah, but you still end up with .something % coverage
Evan Tahler @evantahler Jan 10 09:29
oh yeah, no one is ever 100%
the tests were really cool though... they would generate ~ 100 maps or so in the test and make sure the unit could reach the other side. The maps were random each time so as the project grew they had a record of all the cases the AI failed
Synth Meat @synthmeat Jan 10 09:30
coolio. i have no clue what to do with FAKEREDIS=false though. i've pushed what i thought was the fix though
ok, i write those too, mostly in form of bot players
but never used testing frameworks and such
i use bots for both functional and scalability "tests"
(so it's good that actionheroClient exists)
Evan Tahler @evantahler Jan 10 09:31
bots = "integration tests" I would imagine
Muhamed Krlić @l0oky Jan 10 09:31
yeah
Evan Tahler @evantahler Jan 10 09:31
evantahler/actionhero#747 looks good!
Muhamed Krlić @l0oky Jan 10 09:31
just different by the name
Synth Meat @synthmeat Jan 10 09:31
evantahler: ok that, but help me fix node-resque thingie :)
Muhamed Krlić @l0oky Jan 10 09:32
@synthmeat Weechat can't ping a gitter user like that.
and the other way around I guess
Synth Meat @synthmeat Jan 10 09:32
ah, i have to @, ok
Evan Tahler @evantahler Jan 10 09:34
here's where the pull request magic comes in
I can check out your pull: git fetch && git checkout refs/pull/origin/113
and then I can mess with it too, and we can both work on the same PR
Muhamed Krlić @l0oky Jan 10 09:35
Interesting!
Evan Tahler @evantahler Jan 10 09:35
checking on it now
Synth Meat @synthmeat Jan 10 09:36
what's riot using actionhero for?
Muhamed Krlić @l0oky Jan 10 09:37
riot the game making company?
Synth Meat @synthmeat Jan 10 09:37
yeah
Muhamed Krlić @l0oky Jan 10 09:37
wow, I am guessing experiments
where did you find out about that?
Synth Meat @synthmeat Jan 10 09:39
http://www.actionherojs.com/learn-more/
bottom
yeah, i'll use it at the very least for prototyping
(prolly production too)
Muhamed Krlić @l0oky Jan 10 09:46
wow ok
Evan Tahler @evantahler Jan 10 09:52
I guess I'm not supposed to talk about what those vendors are using it for specifically, but everyone on that list has used it in production I believe.
add yourselves when the time comes
Synth Meat @synthmeat Jan 10 09:54
Evan Tahler @evantahler Jan 10 09:56
huh, I was wrong... and can't push to PR
I'll comment where the answers are
Synth Meat @synthmeat Jan 10 09:57
evantahler: figured out what was wrong?
omichowdhury @omichowdhury Jan 10 10:00
synthmeat has to give you access to his fork for you to be able to push to his PRs
Muhamed Krlić @l0oky Jan 10 10:00
^
Synth Meat @synthmeat Jan 10 10:01
"or he just fixes it himself because he's to blame" :P
@synthmeat waits for travis
Synth Meat @synthmeat Jan 10 10:02
yeah, it'll pass
omichowdhury @omichowdhury Jan 10 10:02
yeah on my team we would send a PR to someone's fork if that needed to be done, but that's rare
Synth Meat @synthmeat Jan 10 10:02
or not
Muhamed Krlić @l0oky Jan 10 10:03
@evantahler Why are remote procedures not defined seperately? Instead you can evaluate everything that api object holds.
like api.remoteprocedures = { 'log' : api.log, 'ringBell': function(){...} } ?
Synth Meat @synthmeat Jan 10 10:08
@evantahler pass! there's was something additional in test/core/scheduler.js
these tests are fun
they bring tension to coding experience
Muhamed Krlić @l0oky Jan 10 10:14
yeah, you have to test it somehow not to mention repeat tests
@synthmeat goes off to make pizzas
Synth Meat @synthmeat Jan 10 10:15
@evantahler, thnks for help
Muhamed Krlić @l0oky Jan 10 10:15
mnogi nasi ne vole testove, kazu gubljenje vremena :)
Synth Meat @synthmeat Jan 10 10:17
l0oky, they just need to grow up, like me :)
um, not "to be grown up like me" but as in "i need to grow up too"
Muhamed Krlić @l0oky Jan 10 10:19
hhahaha, didn't notice it until you brought it up
Evan Tahler @evantahler Jan 10 10:19
I think this translate app misses some of the nuance https://translate.google.com/?ie=UTF-8&hl=en&client=tw-ob#hr/en/mnogi%20nasi%20ne%20vole%20testove%2C%20kazu%20gubljenje%20vremena
Muhamed Krlić @l0oky Jan 10 10:22
Yeah we tend to write ž (zsch) like z and š (sch) like s. This is the real translation-ish
Many of us don't like tests, they say It's a waste of time
Synth Meat @synthmeat Jan 10 10:23
Muhamed Krlić @l0oky Jan 10 10:23
Us as in our oldschool programmers
Evan Tahler @evantahler Jan 10 10:29
a semver question for node-resque
@synthmeat only changed the name of a config setting
so I think a middle version change is OK: 1.2.0 => 1.3.0
but, technically, your old config settings won't work
so that is a breaking change
so should this force the version to go from 1.2.0 => 2.0.0?
Muhamed Krlić @l0oky Jan 10 10:31
Increment middle version by two. That'll show the significance of the change
Evan Tahler @evantahler Jan 10 10:31
lol
I'll do the middle one for now... if anyone gets mad, we can do a major version
Muhamed Krlić @l0oky Jan 10 10:32
yeah
I mean, I know many dependencies I've used had the same issue. Small change, big implications with middle version incremented.
Evan Tahler @evantahler Jan 10 10:36
@synthmeat is fast!
Muhamed Krlić @l0oky Jan 10 10:37
He's probably enjoying his pizza along the way
Evan Tahler @evantahler Jan 10 10:39
@l0oky that's a good community idea! we should all eat pizza at the same time around the world and take photos. "the sun never sets on the (pizza-loving) actionheros"
Muhamed Krlić @l0oky Jan 10 10:39
haha
Evan Tahler @evantahler Jan 10 10:39
distributed asynchronus pizza.
Muhamed Krlić @l0oky Jan 10 10:39
It would be synchronous If It's at the same time haha
Evan Tahler @evantahler Jan 10 10:41
something about the rotation of the earth and ms time drift :D
Muhamed Krlić @l0oky Jan 10 10:41
But since It's all relative :) async it is
:D
Evan Tahler @evantahler Jan 10 10:41
actually, fun fact, I know gitter themselves use node-resque
and they might even use actionhero
lemme ask them
Muhamed Krlić @l0oky Jan 10 10:42
interesting :)
Evan Tahler @evantahler Jan 10 10:44
thanks @synthmeat, all merged in!
it's pkg going forward
Muhamed Krlić @l0oky Jan 10 10:46
@evantahler I see you've prepared v12-legacy branch :)
Evan Tahler @evantahler Jan 10 10:46
yeah... I don't really have any plans for it... but I'm sure it will come up
some critical bug that needs to be fixed or something
probably with the ws package
Muhamed Krlić @l0oky Jan 10 11:14
@evantahler Why are remote procedures not defined seperately? Currently you can evaluate everything that api object holds.
Wouldn't it be better to like have api.remoteprocedures = { 'log' : api.log, 'ringBell': function(){...} } ? and then rpc those?
Evan Tahler @evantahler Jan 10 11:18
probably... but that list of methods is really long
and then if there is any method you define in an initilizer, you would also have to add it
like api.database.reconnectToDatabase after one node adds a new table or something
hence the eval hack
Muhamed Krlić @l0oky Jan 10 11:20
maybe just flag the methods you want for rpc ?
api.database.reconnectToDatabase.remoteprocedure = true
eval is doing a good job If you want It done quick and dirty ..
I think It's good as it is for now :)
as long as It's executed by trusted sources
Evan Tahler @evantahler Jan 10 11:45
Yeah, that's what the cluster security key is for
Muhamed Krlić @l0oky Jan 10 11:46
You mention something about a api.config.serverToken is that it?
Evan Tahler @evantahler Jan 10 12:22
yep
Synth Meat @synthmeat Jan 10 23:35
bowie died
and i've just literally stolen an album from him last night
https://www.youtube.com/watch?v=KaOC9danxNo
Evan Tahler @evantahler Jan 11 12:33
I know :(
here's me from halloween a while back
http://i.imgur.com/8qqOfYC.jpg
I lied, here's one more v12 release https://github.com/evantahler/actionhero/releases/tag/v12.5.0
This change renames the variable package in redis config to pkg. package is a reserved word in javascript and should not have been used.
The package node-resque, which actionhero relies on, has also updated this configuration setting.
Muhamed Krlić @l0oky Jan 11 12:39
so babel is supported with v12 now I guess :)
I don't know what's all the fuss with thirdparty js compilers/syntax stuff
I like ES5 :)
Konstantin Nesterov @wasd171 Jan 12 10:43
Guys, just a quick question: I am creating SPA and I need to match every non-action and non-js request to a single index.html. Is it possible (with no heavy cracking) with AH or shall I move file serving to something like Express/Koa?
Nick Collins @ndcollins Jan 12 12:19
Personally, I’d leave all the static file serving to NGINX, and configure your location to direct all requests to index.html, then have AH running on your API server, something like Heroku, and have all your API action calls go to api.yourdomain.tld
or something along those lines
Evan Tahler @evantahler Jan 12 12:33
+1 for @ndcollins That's why by default all actions are behind an /api route as well.
But @wasd171 you can do It. Make a catch all action which returns html.
Use the new TrailingPathParts in the router to match it.
Konstantin Nesterov @wasd171 Jan 12 12:56
@evantahler nevermind, left it to nginx =)
Konstantin Nesterov @wasd171 Jan 13 04:15
One more question: I'd like to use RethinkDB and to fire an event on db change via websockets for clients to refetch data. As I understand, the valid place for it would be in tasks, but this task never ends, is that ok for AH? What is a preferred way to handle it?
Nick Collins @ndcollins Jan 13 08:41
@wasd171 This may not be the correct AH way of doing things, but for continuous tasks like that I typically put that code into an initializer that would be responsible for listening for those db changes, then send the notification over WS
I also typically use initializers to bootstrap my services to promote a more DRY approach so that the logic in my actions is pretty much calling one of those service methods (which is wrapped in a bluebird promise) and returning the results, if needed to the client
Greg Coonrod @gcoonrod Jan 13 11:15
@evantahler Is it normal that when using api.specHelper.connection() with api.specHelper.runAction() that the returned connection object does not have a responseHttpCode?
Evan Tahler @evantahler Jan 13 13:12
Yep. Because it's not http!
That's only for the web server
Greg Coonrod @gcoonrod Jan 13 13:15
how would I tailor the test connection to always be for the web server? My team doesn't currently use any of the other servers.
Evan Tahler @evantahler Jan 13 13:17
If you need to actually test Http then do that. Use the request package or similar.
The spec helper tests only the generic and purposely agnostic case of actions.
Greg Coonrod @gcoonrod Jan 13 13:18
we're testing actions, but we only service actions through the web server. So one of our common assertions is on the http response from the action.
Perhaps thats a poor testing assumption
Angelo Rodrigues @AngeloR Jan 13 14:01
@gcoonrod I don’t think that’s necessarily a bad assumption, unless you’re making your actions available over not web servers in AH.
Evan Tahler @evantahler Jan 13 17:23
It's a totally fine assumption... As long as you test with that assumption consistently.
Check out how ah core does it in the web server tests.
'''
it('params work', function(done){
request.get(url + '/api?key=value', function(err, response, body){
body = JSON.parse(body);
body.requesterInformation.receivedParams.key.should.equal('value')
done();
});
});
Testin http requires http
Krishna Glick @krishnaglick Jan 16 22:56
I'm running some tests and they're failing in the after function. I call actionhero.stop and the promise times out. I've set the level to debug, commented the exports.test, and ran as -verbose but it still hangs without letting me know why. Any suggestions? Google didn't turn up anything.
Krishna Glick @krishnaglick Jan 16 23:29
I know that's a pretty undetailed error report but I'm not sure what steps to take to trace it down.
Evan Tahler @evantahler Jan 17 00:07
Check out actuonhero,s internal tests. They stop and start the server all the time. You can also turn logging on for the test ENV. That should help
Krishna Glick @krishnaglick Jan 17 09:26
Running mocha tests in the actionhero folder results in a bunch of failures. I'm using Wascally (RabbitMQ) in my app. If my rabbitmq server is running than ActionHero fails to shutdown. If my rmq server isn't running then it shuts down fine. I am confused.
Evan Tahler @evantahler Jan 17 09:32
well, how do you stop the rabbitMQ server in your stop() block in your initilizer? I'm betting that you can't start the server again the next time because the port is in use from the first test suite
Krishna Glick @krishnaglick Jan 17 09:37
I previously didn't have to explicitly stop the rabbitMQ server. I did change how the configuration was loaded up. I'm looking to see if I screwed up the data structure somewhere.
Krishna Glick @krishnaglick Jan 17 09:46
I'm going to table this for now. Dunno why it's acting up. I'll dig deeper later. Thanks!
Evan Tahler @evantahler Jan 17 10:54
good luck!
For the folks thinking about plugin auto-registration and nesting: What do you think about this crazy idea? https://github.com/evantahler/actionhero/issues/727#issuecomment-172363603
I think unix may have solved this for us already...
Muhamed Krlić @l0oky Jan 17 12:50
@evantahler I am pretty unfamiliar with the symlink concept? What is it?
Evan Tahler @evantahler Jan 17 17:22
Symbolic links? Perhaps known as aliases?
Angelo Rodrigues @AngeloR Jan 17 17:22
on windows they're known as "junctions"
but basically it's aliasing one thing as another.
it's basically saying "this thing really means this other thing"
in this case, utilizing directories
Evan Tahler @evantahler Jan 17 18:02
nice @AngeloR
any more thoughts?
Krishna Glick @krishnaglick Jan 18 07:50
Just a side note. I fixed my problem. Still not sure what the issue was, but it was in my after block. Just replaced it with what I had in my other test and magic.
Krishna Glick @krishnaglick Jan 18 12:43
Is there an issue with how actionhero works that prevents node-inspector to hit breakpoints in tasks?
Evan Tahler @evantahler Jan 18 13:25
Not that I've heard of. I've personally never tried it though
Krishna Glick @krishnaglick Jan 18 13:26
What do you use to debug?
Evan Tahler @evantahler Jan 18 18:11
logging? I've used node-inspector before, just not in tasks.
@jacobbubu are you around these days?
@krishnaglick I'll give it a whirl
Muhamed Krlić @l0oky Jan 19 02:52
@evantahler I have a windows machine. What do you want me to do? run tests from plugins branch?
Muhamed Krlić @l0oky Jan 19 02:57
I remember trying to run actionhero tests and many of them failed, but travis passed. Do I need to install something on my linux to get actionhero passed?
I'll try and test then send you the results
Evan Tahler @evantahler Jan 19 07:37
The last time I tried on Windows, over a year ago, everything passed. Can you first try the master branch @l0oky ?
Evan Tahler @evantahler Jan 19 10:25
@krishnaglick yeah, node debugger works fine for tasks
here's my simple test task:
var task = {
name: 'sayHi',
description: 'I will say hello',
queue: 'default',
plugins: [],
pluginOptions: [],
frequency: 0,
run: function(api, params, next){
api.log("HELLO");
next();
}
};
exports.task = task;
and here's it working
http://i.imgur.com/3RF2EYk.png
I ran actionhero using 'real' redis: FAKEREDIS=false ./node_modules/.bin/node-debug --web-port=8081 bin/actionhero
and then enqueued the job in another console instance FAKEREDIS=false ./bin/actionhero enqueueTask --name sayHi
RENARD Laurent @lorenzofox3 Jan 19 19:31
https://github.com/pillarjs/node-frameworks ;)
Evan Tahler @evantahler Jan 19 22:24
Add us!!
That's cool.
uraio @uraio Jan 20 05:51
Instead of api response I would like to make a http redirect. Actionhero supports this?
Evan Tahler @evantahler Jan 20 11:31
Sure! Just set the headers.
Muhamed Krlić @l0oky Jan 21 08:58
Does actionhero use isarray, inherits, core-util-is, process-nexttick-args modules?
12.5.0
because I can't run mocha test It says its all missing these, and It's not even defined in package.json
Muhamed Krlić @l0oky Jan 21 09:05
nevermind, had some issues with npm
Greg Coonrod @gcoonrod Jan 21 10:43
Those of you running ActionHero clusters using AWS Elasticbeanstalk, how are you designing your health checks? Specifically, how do you tell an ELB that a given instance is healthy?
omichowdhury @omichowdhury Jan 21 14:55
@gcoonrod So we have a really simple action that just returns { status: "OK" }, that tells us the webserver is fine. We haven't figured out a solution for worker instances
Evan Tahler @evantahler Jan 21 15:12
I monitor workers indirectly. Resque queue length is the best indicator. You can also check on if a node has any working workers.
Greg Coonrod @gcoonrod Jan 21 15:30
@evantahler I need my nodes to respond to EBS health check calls, for task worker nodes, how do I "know" the node is healthy?
Evan Tahler @evantahler Jan 21 18:27
I would do the following:
fix the number of workers (min 10, max 10; something like that)
write a health check that uses the api.tasks.details api to check that all 10 workers are either A) idle or B) working on something
you can also then check the queue lengh itself in another endpoint for autoscaling
if the queue is longer than 1000 for instance, spin up more worker nodes!
you can also get the worker start time
so if you know your jobs shouldn't take longer than 10 min, you can do that math in the heath check too
Greg Coonrod @gcoonrod Jan 21 18:34
Thanks @evantahler !
Evan Tahler @evantahler Jan 21 18:35
details will get data for all the workers in your cluster, so you'll need to do some host name comparisons or something
but that should be the only complex part
Muhamed Krlić @l0oky Jan 21 23:14
@evantahler Why are my plugin and master branch tests not passing? It seems like it times out on most of these :)
that gist contains 2 files btw..
Krishna Glick @krishnaglick Jan 22 08:28
There a way for me to add folders to actionhero's watch list?
Evan Tahler @evantahler Jan 22 09:32
For developer mode?
WatchFileAndAct would be the method
Krishna Glick @krishnaglick Jan 22 11:04
Can I give that a folder and have it watch for changes in the folder as well as to files in that folder?
Looking through src doesn't look like it, but...
Evan Tahler @evantahler Jan 22 11:16
Nope, but checkout the glob package on NPM. You can loop though all files easily enough.
Krishna Glick @krishnaglick Jan 22 11:49
That's what I'm doing now, was just wondering if it gave me an easy cop-out method.
Greg Coonrod @gcoonrod Jan 22 14:08
Has anyone seen the following error when running an npm install of Actionhero?
> actionhero@12.5.0 postinstall /home/jenkins/charlie.casctesla.com/hero/node_modules/actionhero
> echo 'To generate a new actionhero project, run "node ./node_modules/.bin/actionhero generate"'
To generate a new actionhero project, run "node ./node_modules/.bin/actionhero generate"
npm WARN engine hoek@2.16.3: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.33","npm":"2.6.1"})
npm WARN engine boom@2.10.1: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.33","npm":"2.6.1"})
npm WARN engine cryptiles@2.0.5: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.33","npm":"2.6.1"})
npm ERR! cb() never called!
Evan Tahler @evantahler Jan 22 14:37
Weird! Nope
What os/node?
Greg Coonrod @gcoonrod Jan 22 14:53
Ubuntu with node 0.10.33 in this case. And the npm install has finished before, this is new.
Evan Tahler @evantahler Jan 22 15:05
I would suggest going package by package and trying to install. Delete one, npm install, repeat.
Greg Coonrod @gcoonrod Jan 22 15:07
this is on a remote build box.
Nathan @BoLaMN Jan 23 04:16
I'd upgrade your node version, many packages are coming with peerDependacies which the older npm versions don't know about
Plus v4 is stable now and v0.10 is out dated by far.
Greg Coonrod @gcoonrod Jan 23 07:30
@BoLaMN we are in the middle of an upgrade to node 4 and an upgrade from Actionhero 10 to 12. Our PR build systems must be able to switch versions of node on the fly while building. Which has been giving us issues. Overall the Actionhero upgrade process has been quite painful :(
Evan Tahler @evantahler Jan 23 08:58
Take notes and let us know what we can make better!
Evan Tahler @evantahler Jan 26 22:26
@gcoonrod any specific notes you have? How did the upgrade go? I never want to stop forward progress for the past, but we can certainly do better than we have been ( almost nothing)
Greg Coonrod @gcoonrod Jan 27 05:20
@evantahler I will pull together some notes soon.
Evan Tahler @evantahler Jan 27 07:25
Cool.
peterkingsbury @peterkingsbury Jan 27 08:03
@evantahler hey evan! are there plans for a resque-web style interface available as part of AH?
Evan Tahler @evantahler Jan 27 20:02
Not that I know of... But that would make an awesome plugin!
There's an issue for it in the node-resque project
@peterkingsbury you should totally make one ;)
Josef Blank @joblab Jan 28 05:50
Hi! Is anyone using the ActionHeroClient with SystemJS as module loader? Whenever I try to import my AH Client, I'm getting "Cannot set property 'Primus' of undefined" since this is undefined in line 8...
Evan Tahler @evantahler Jan 28 08:34
nope, never tried system js
I would ask this question to someone in the primus project maybe? primus/primus#402
n-s-k @n-s-k Jan 28 08:35
Hi, newbie here, stupid question, few days ago everything was ok on windows, now I get:
λ npm start
> my_actionhero_project@0.0.1 start C:\####
> actionhero start
info: actionhero >> start
2016-01-28T16:24:23.793Z - notice: *** starting actionhero ***
and it hangs there forever... any advice on how to debug that?
Dan @SDSWanderer Jan 28 11:23
Hi!
I do some job using periodic task in non cluster mode started app, with minTaskProcessors=1. Scheduler works fine, but sometimes worker process stopped, and restarted again. I see next entries in log:
2016-01-28 21:07:33 - info: worker: job success default workerId=1, class=doJob, queue=default, result=undefined
2016-01-28 21:07:33 - info: worker: started workerId=2
2016-01-28 21:07:33 - info: worker: ended workerId=2
In this second my app totally down and not listening network port.
So this is critical problem for me, any ideas why this happening?
Evan Tahler @evantahler Jan 28 12:18
@n-s-k change your log level (config/logger) to 'debug' and you can see whicih initilizer it gets stuck on
@SDSWanderer what's the problem with that log? it seems that the job was completed successfully? A second worker was started for a little and then stopped, as it wasn't needed
that looks right to me
as for not listining, we'll need a lot more detail: node version, os, AH version, port, etc
n-s-k @n-s-k Jan 30 03:04
@evantahler that's exactly what I needed, thank you. For the record, my Redis server was down and I had not removed the REDIS_HOST environment variable.
n-s-k @n-s-k Jan 30 03:31
I have just noticed something, I'm not opening an issue ticket as it might well be node/ignorance related, debugging AH 12.5 on Windows seems to fail for any version of node (x64) > 4.2.4:
With node 4.2.6, after the websocket init: Process finished with exit code -1073741819 (0xC0000005).
With node 5.5.0, any breakpoint not at the beginning of the code (e.g. in the actions) won't be caught (by IntelliJ or NTVS).
Krishna Glick @krishnaglick Feb 01 08:18
n-s-k: I have the same problem w/ node-inspector and assumed I had done something wrong.
Jeremy Miller @JeremyMiller Feb 01 13:32
Hello, does anybody know if there is a way to get the http-headers sent on a websocket connection?
In particular, I'm trying to get the value of x-forwarded-for
rawConnection.req seems to be undefined.
Jeremy Miller @JeremyMiller Feb 01 13:38
That is, headers sent by the client, not by the server.
Krishna Glick @krishnaglick Feb 01 13:57
If you're the client you should be able to see your own headers.
Jeremy Miller @JeremyMiller Feb 01 14:09
I'm not the client.
We have cloudflare between our clients and our servers, which puts the real client's IP in the x-forwarded-for header
Krishna Glick @krishnaglick Feb 01 14:14
http://www.actionherojs.com/docs/#the-data-object
Jeremy Miller @JeremyMiller Feb 01 14:15
data.connection.rawConnection.req is undefined
It seems it's only populated on non-websocket connections
Evan Tahler @evantahler Feb 01 14:16
yep, because by the time you get a websocket, the orignal "req" has been upgraded to a socket
that said, you do have some other stuff availaible to you
https://github.com/primus/primus#sparkheaders
so try connection.rawConnection.headers
or, I guess, connection.rawConnection.address
we should fix that within the core
let me try it out
whoops! ha, that is what we are doing
Jeremy Miller @JeremyMiller Feb 01 14:19
Ah, thanks Evan.
Evan Tahler @evantahler Feb 01 14:19
so the connection object is already hydrated with data from the headers if present
Jeremy Miller @JeremyMiller Feb 01 14:20
So is the data.connection.remoteIP using the x-forwarded-for address?
Evan Tahler @evantahler Feb 01 14:20
connection. remoteIP is the connonical, agnostic way to get what you are after
yep
Jeremy Miller @JeremyMiller Feb 01 14:20
Ah, great.
I wasn't sure.
Evan Tahler @evantahler Feb 01 14:21
primus has a whole lib just for this: https://github.com/primus/forwarded-for
Jeremy Miller @JeremyMiller Feb 01 14:22
nice.
Dj Kilgore @djkilgore Feb 04 14:54
so I have some action middleware which is requiring an argument, that works fine, but that argument does not seem to be available in data.params in the action run function. How do I get it?
without adding it to all of the actions that use that middleware input reqs
Dj Kilgore @djkilgore Feb 04 15:02
can I just set data.actionTemplate.inputs.whatever = data.params.whatever in the middleware preprocessor, or is that going to make me have a bad time
Evan Tahler @evantahler Feb 04 19:33
You can... But it would be best to modify the connection. Connection.stuff
Dj Kilgore @djkilgore Feb 04 19:49
roger, so just set data.connection.params.thing = data.params.thing
looks like it works
ytmnd
ramsaybr @ramsaybr Feb 04 22:43
Hey @evantahler ! I need to save a record of each request to a redis service at some point during the processing of an action. Right now I have this built as an action postProcessor. But I'm realizing that alternatively I could make this a task that gets immediately enqueued from the action itself. Either is fine: I just need to get the data written to redis. From a throughput and efficiency standpoint which is the superior option?
@evantahler (THANKS!)
Evan Tahler @evantahler Feb 04 22:59
Well... How important is it? If it's essential, do it in the request flow with a middleware. Otherwise, a task is fine. But that writes to redis too... So it's a wash?
ramsaybr @ramsaybr Feb 04 23:03
That's kind of what my assumption was. Admittedly I'm not solid enough in my understanding of the node event loop to perfectly understand whether or not placing it in the middlewear or a task makes more sense.
But if you think it really doesn't matter then middlewear it is.
ALSO: @evantahler you're the best
donnyhardyanto @donnyhardyanto Feb 05 06:57
Hi @evantahler , @l0oky , remember bug: async.c:149: uv__async_io: Assertion `n == sizeof(val)' failed. It always show up when only single worker/process with huge requests, but it didn't show when using clustered worker using startCluster
So I think it is save for production when using startCluster. I have deploy and monitor for a month there is no problem.
*safe
Evan Tahler @evantahler Feb 05 07:29
I'm also fairly sure that is a Windows bug
donnyhardyanto @donnyhardyanto Feb 05 08:15
Actualy it is linux bug. In Windows never show up event I give 4x amount huge traffic that triggeres bug in Linux. I use Debian dan Ubuntu
*even
donnyhardyanto @donnyhardyanto Feb 05 08:21
@evantahler, what task plugin need to be use for serialize jobs in queue, so only one process per queue, for application like inventory information system? Can queueLock be used?
Mike Kozak @meteormanaged Feb 05 11:21
right.
Evan Tahler @evantahler Feb 05 14:20
yeah. that should work
Dj Kilgore @djkilgore Feb 05 14:49
how can I prevent defaultRoom and anotherRoom from being created on startup without modifying stuff outside of my projects code (ie: node_modules/actionhero/config/api.js)
Dj Kilgore @djkilgore Feb 05 16:14
also, is there a way to maintain a connection id across tests using specHelper? For instance I have a test which checks a connection was removed from a chatRoom, but because the connection id is not the same the test fails...
Dj Kilgore @djkilgore Feb 05 16:31
like is there a way to give specHelper a connection_id to use
Chad Robinson @crrobinson14 Feb 05 19:14
You can just keep a reference to the connection, if they're in the same file. I have tests where a before handler creates a connection and makes a record with it (the test checking this was successful) and a later test deletes it with both a new connection and the original one (which is performing an access check). It's harder to do storage cross-file though because most runners will be starting / tearing down AH in between.
Hey folks, long time no speak.
Got a weird one tonight. One of my task nodes is running in startCluster mode. it runs fine, processes jobs, etc. But I have this filling my logs
Feb 03 14:39:33 task1 default: info actionhero member actionhero-worker-1 has joined the cluster
Feb 03 14:39:33 task1 default: info actionhero member actionhero-worker-1 has joined the cluster
Feb 03 14:39:48 task1 default: info actionhero member actionhero-worker-2 has joined the cluster
Feb 03 14:39:48 task1 default: info actionhero member actionhero-worker-2 has joined the cluster
Over an over. There are no errors reported in either the main log or the cluster log. Everything seems fine - it just seems to be restarting constantly.
Note that nothing ever reports something as having left the cluster.
Chad Robinson @crrobinson14 Feb 05 19:22
I have a multi-node cluster and noticed that every node has the same actionhero-worker-1 and -2 going on. Could it be related?
Evan Tahler @evantahler Feb 05 22:25
well... that's communicated over redis... so somwhere that is happening
but... which node? Somewhere someone is freaking out and crashing
@/all I've merged the v13.0.0 release canditdie to master!
PLEASE help and test it out!
SO MANY CHANGES
(which are enumerated here: evantahler/actionhero#736)
This message was deleted
Ha! There are so many changes that Gitter won't let me paste them all :D
Evan Tahler @evantahler Feb 05 22:30
@djkilgore just set api.config.general. startingChatRooms = {}
Synth Meat @synthmeat Feb 06 01:29
@evantahler: congrats on release
@synthmeat goes to check it out
Dj Kilgore @djkilgore Feb 06 05:20
thanks evan, that does work. I just found it confusing that if I only had defaultRoom in my startingChatRooms config, the other 2 are still started from the base actionhero config
Dj Kilgore @djkilgore Feb 06 05:43
also thanks to ccrobinson above, I didnt realize you could pass a connection to specHelper. I probably should have just looked at https://github.com/evantahler/actionhero/blob/master/initializers/specHelper.js#L120
Chad Robinson @crrobinson14 Feb 06 09:46
@evantahler Thanks, I'll do some more debugging. THere's something else weird tho. I have a task with a frequency of 60000 that's running every 5 sec
Feb 06 09:45:47 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:45:52 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:45:57 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:46:02 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:46:07 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:46:12 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 06 09:46:17 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
var Promise = require('bluebird'),
task = {
name: 'indexUsers',
description: 'Index user accounts',
queue: 'low',
plugins: [],
pluginOptions: [],
frequency: 60000
};
I can't for the life of me figure out why this task is running more than once a minute. All the other tasks run exactly as scheduled.
Evan Tahler @evantahler Feb 06 09:52
@crrobinson14 can you share your whole file? 5s is the default worker, so I'm going to guess its getting re-enqueued as fast as it completes. That, or you might have it enqueued like 100's of times by accident... was it always periodic? Use a tool like redis commander http://joeferner.github.io/redis-commander/ to actually look at your redis data and see what's in there
the resque data structure is really simple to understand... just a bunch of arrays (lists) with names like resque:name_of_queue
I'm betting on something wierd with your promise @crrobinson14 which is not returning the frequency object properly... so it's just enquing the task a ton of times
Chad Robinson @crrobinson14 Feb 06 19:07
var Promise = require('bluebird'),
task = {
name: 'indexUsers',
description: 'Index user accounts',
queue: 'low',
plugins: [],
pluginOptions: [],
frequency: 60000
};
task.run = function(api, params, next) {
var indexedCount = 0;
api.models.user.findAll({
// some query params
}).then(function(users) {
// some indexing checks for each user
}).catch(function(e) {
api.log('Error querying for users to index', 'error', e);
}).finally(function() {
// All goes well - we always end up here
next(null, 'Indexed ' + indexedCount + ' users');
});
};
exports.task = task;
I trimmed it a bit to save space but nothing relevant - it always succeeds (no errors thrown).
This was always a periodic task. And you're right, it's just immediately re-enqueuing at the base task poll frequency.
Krishna Glick @krishnaglick Feb 07 17:03
How would I configure actionhero to utilize this node option? http://prestonparry.com/articles/IncreaseNodeJSMemorySize/
Dj Kilgore @djkilgore Feb 08 06:55
so I have a bunch of tests running specHelper, just started getting this...
(node) warning: possible EventEmitter memory leak detected. 11 exit listeners added. Use emitter.setMaxListeners() to increase limit.
am I doing something incorrectly to cause that
Evan Tahler @evantahler Feb 08 20:22
@djkilgore well... share a test case so we can see what you are doing!
@krishnaglick node --max_old_space_size=4096 ./node_modules/bin/actionhero start ?
@crrobinson14 your use of finally I think is the problem
If I read that correctly, the next should be in the then block where you get the users returned
Evan Tahler @evantahler Feb 08 20:27
remove the finally entirely
Chad Robinson @crrobinson14 Feb 09 04:27
@evantahler The structure of the call doesn't seem to matter. I can comment out the entire block and just call next and it has the same behavior.
The only difference I can think of between this and other AH setups I've done is this time I'm trying to have a number of different queues ('high', 'med', 'low', etc.) and running different task nodes against those queues.
FWIW next-in-finally isn't a bad pattern. It's a little tricky to recover and restart a failed job outside of code. In the example above, I'd much rather be able to fix a database issue preventing an indexer from running while still having the indexer continue TRYING to run, without having to add code to additionally reschedule the job.
Evan Tahler @evantahler Feb 09 07:57
The queues shouldn't matter at all... that's the point of the thing! And we've got enough tests around that in actionhero and node-resque that I don't think anything is going wrong there.
How do you resolve the promise within the then block after working on your users (such that finally will fire)? I've still got my money on a prommise-related issue
Evan Tahler @evantahler Feb 09 08:57
@crrobinson14 I've had quite a few promise-related issues myself with sequelize. For what you are doing, I always end up using async within the then block
something like this:
var async = require('async');
exports.task = {
name: 'notifier-all',
description: 'notifier-all',
frequency: (1000 * 60),
queue: 'default',
plugins: ['queueLock'],
pluginOptions: { lock_timeout: 61 },
run: function(api, params, next){
api.models.team.findAll().then(function(teams){
var jobs = [];
teams.forEach(function(team){
jobs.push(function(done){
api.tasks.enqueue("notifier-team", {teamId: team.id}, 'default', done);
});
});
async.parallel(jobs, function(error){ next(error); });
}).catch(next);
}
};
Chad Robinson @crrobinson14 Feb 09 10:35
@evantahler I know Promises can cause all sorts of grief if not managed... But I can reproduce this behavior even with this task definition:
task.run = function(api, params, next) {
next();
return;
};
Evan Tahler @evantahler Feb 09 11:29
I'm stumped :(
Node version, action hero version, etc?
Synth Meat @synthmeat Feb 09 12:02
evantahler: 13 still not published on npm?
forgot @. @evantahler
Chad Robinson @crrobinson14 Feb 09 12:28
It must have been something in Redis because a FLUSHDB and restart solved it. I should have taken a data dump before I tried that. :( Guess I'll watch for it to happen again - and hope it doest.
Evan Tahler @evantahler Feb 09 14:10
ouch... well, glad it is fixed @crrobinson14 !
If you see it again, and you are able, please share your dump!
@synthmeat giving it week for feedback
Chad Robinson @crrobinson14 Feb 09 16:48
@evantahler On a related note, I follow the best practice of deploying via kill -USR2 masterPid. But when run in cluster mode this doesn't seem to always pick up config file changes. Is this expected? I have to fully down/restart the service to pick up a config change.
Evan Tahler @evantahler Feb 09 18:12
That's not expected at all!
Can you reproduce? I've never seen anything like that. Can you confirm the child processes are swapping out via pid change?
Chad Robinson @crrobinson14 Feb 09 20:23
@evantahler The only thing I can think of related to the first issue is processes in a cluster conflicting with one another by name? They all reported as starting as actionhero-worker-1 and actionhero-worker-2 (I have these on boxes where startCluster starts 2 children automatically.) One of the things I changed in that deployment is to pass in workerTitlePrefix with a unique value for each node. It doesn't seem like that should be the issue... but perhaps?
It's all I've got. I'll watch for it.
Everything seems clean now after a FLUSHDB and a couple of restarts, plus that. TBH I don't really understand the inteactions between the node-resque data structures, despite repeated poking around. Are there any web/other management tools for it? I found a basic Web interface that showed jobs and queues, but it wasn't very sophisticated, particularly at listing and dealing with failed entries.
Evan Tahler @evantahler Feb 09 23:40
The ruby UI is the best
Check it out here:
https://github.com/taskrabbit/node-resque/tree/master/resque-web
But the next time you HUP check the pids
Krishna Glick @krishnaglick Feb 10 06:43
@evantahler That did it, thanks! I wish 'actionhero start' took those arguments as well. ^^
Krishna Glick @krishnaglick Feb 10 07:09
Is there a recommended method of profile ActionHero? --prof gets me some metrics but most profilers want an index.js-type thing.
salles @sallespro Feb 10 08:29
@evantahler i have been tinkering with Primus. i am curious about your design decisions to make use of its abstractions to build action hero, like rooms, the connection ids..
salles @sallespro Feb 10 11:15
so the question is : how did you design the connection id in relation to HTTP ? did you consider bundling them ?
my question is to figure out a way to match HTTP loggeg users with their corresponding socket connections.
Evan Tahler @evantahler Feb 10 13:02
@sallespro we went though a bunch of WS transports: socket.io in the begining, then faye
they all had failings
we also wanted an agnostic cluster proticol so it would work with other transports
so primus as a wrapper lets you pick the underlying transport (faye, ws, engine.io, etc) but then we can always use the normal connection middleware(s). It's great
to link socket to http connections, it's easy!
Synth Meat @synthmeat Feb 10 13:04
@evantahler, go upvote! https://news.ycombinator.com/newest
Evan Tahler @evantahler Feb 10 13:04
@sallespro http://www.actionherojs.com/docs/#linking-websockets-to-web-auth connection.fingerprint is the same
@synthmeat oh?
oh!
Synth Meat @synthmeat Feb 10 13:05
3 similar frameworks got frontpaged today, figured why not
Evan Tahler @evantahler Feb 10 13:05
lol
I would have waited until v13, but what the hell
ha!
Synth Meat @synthmeat Feb 10 13:05
:)
Evan Tahler @evantahler Feb 10 13:06
first mention over 1K days ago -> https://news.ycombinator.com/from?site=actionherojs.com
Synth Meat @synthmeat Feb 10 13:06
yeah, saw those
Evan Tahler @evantahler Feb 10 22:04
@/all version 13 is released!
https://github.com/evantahler/actionhero/releases/tag/v13.0.0
YAY! AND THANK YOU EVERYONE WHO HELPED!
Muhamed Krlić @l0oky Feb 10 22:07
Awesome!
Evan Tahler @evantahler Feb 10 22:13
now everyone tweet about it... evangelize!
Evan Tahler @evantahler Feb 11 07:53
Upvote time!
Reddit: https://www.reddit.com/r/javascript/comments/459ef4/actionherojs_server_v1300_released/
Hacker News: https://news.ycombinator.com/newest
Konstantin Nesterov @wasd171 Feb 11 07:54
It would be really hard to argue with gravitational waves news
Muhamed Krlić @l0oky Feb 11 07:54
hhahah
I know right
Jeremy Miller @JeremyMiller Feb 11 08:11
This message was deleted
Jeff Lee @orangebread Feb 11 09:54
this framework dope af
Greg Coonrod @gcoonrod Feb 11 11:24
@evantahler Do you know of anyone running AH in AWS? After completing the v10 to v12 upgrade (which included an upgrade of node from v0.10 to v4) we've seen a significant increase in the idle CPU usage. As in, we went from single digit idle CPU usage to ~35% idle CPU usage.
Evan Tahler @evantahler Feb 11 11:25
I use it in AWS (on an ubuntu VM)... there are some folks here who use Elastic Beanstalk as well
also, to clarify @gcoonrod that's a good thing: You have more CPU idle, yes?
the inverse of which would be CPU wait, which is bad
Greg Coonrod @gcoonrod Feb 11 11:27
Sorry, I should have said our CPU utilization
the image is for our web server nodes, so no task processing
the AH upgrade happened around 2/2
^ These are our task processing nodes
Nikolay Kostyurin @JiLiZART Feb 11 12:45
Hi, how i can integrate jsonapi.org, currenly i need errors format, like written
Evan Tahler @evantahler Feb 11 12:51
@JiLiZART you can return objects as errors, if that is what you asking
and make middleware to do that for you automagically
@gcoonrod so is your question: "did something change in the release to make the process slower"? if so, you are the first to report something like that, but it certainly could have happened
that said, that was a long time ago :/
there were also some signifigant changes to node-resque, which we use under the hood in there too
but again, no 'slowness' reports that I've seen
oh... with the multi-worker, we are INTENDING To use as much CPU as possible
but that also means that we are working more jobs at once than we would have before
Greg Coonrod @gcoonrod Feb 11 12:54
@evantahler we aren't seeing slowness, we actually see better response times from our web server nodes, its just cpu util at rest is 30% higher than before the upgrade
Evan Tahler @evantahler Feb 11 12:55
what are your min and max task processors set at?
those are the options you have to tweek
Greg Coonrod @gcoonrod Feb 11 12:56
for the webserver nodes there are no task processors
for the task processing nodes min is 2 max is 10
Evan Tahler @evantahler Feb 11 12:56
yeah, that's what I mean
Greg Coonrod @gcoonrod Feb 11 12:56
but we see the same jump in cpu util on both web and task nodes
Evan Tahler @evantahler Feb 11 12:56
in actionhero v10, the min and max was always 1
ahh
then you are the first to report it
Greg Coonrod @gcoonrod Feb 11 12:57
hooray?
Evan Tahler @evantahler Feb 11 12:57
can you make 2 small apps that reproduce this?
or do any tracing to find the slow methods?
Greg Coonrod @gcoonrod Feb 11 12:58
What tools would you recommend for finding slow methods?
Evan Tahler @evantahler Feb 11 12:58
dtrace?
or just timing things and logging it out
you can make a middleware for it
Greg Coonrod @gcoonrod Feb 11 13:00
hmm, I'll have to see if I can get our PMs to let us spend the cycles for an investigation. We're not seeing any service degradation yet, just high cpu util. Which forced us to adjust our auto-scaling settings. If we run into actual performance issues I may be able to get the resources to figure out what is eating up all the extra cycles.
Nikolay Kostyurin @JiLiZART Feb 11 13:06
@evantahler by standard written in jsonapi.org, i need to put serverInformation and requesterInformation to meta object, and display errors inside errors array. how can i do this?
http://jsonapi.org/format/#document-top-level
Evan Tahler @evantahler Feb 11 13:40
@gcoonrod good to hear either way! And I'm happy to hear that actionhero is chugging along for your business!
@gcoonrod can you share what your application is?
@JiLiZART for the auto-generated metadata, serverInformation and requesterInformation, there really isn't a way to move them. you can disable them in the /config/servers/web.js and re-implement them yourself.
for errors in your Actions, just do stuff like next({errorCode: 123, errorReason: 'something broke'})
Nikolay Kostyurin @JiLiZART Feb 11 13:42
okay, but how i can rename error to errors ?
Evan Tahler @evantahler Feb 11 13:42
oh!
Nikolay Kostyurin @JiLiZART Feb 11 13:42
))
Evan Tahler @evantahler Feb 11 13:42
you can't
ha
I missed that
Nikolay Kostyurin @JiLiZART Feb 11 13:43
sad
Evan Tahler @evantahler Feb 11 13:43
actionhero does not follow this spec
if you want to adapt it, send in a pull request!
you can also do this moving automatically in a middleware which would be cool
Nikolay Kostyurin @JiLiZART Feb 11 13:43
oh, i will try
Evan Tahler @evantahler Feb 11 13:43
move error -> errors, etc
then put that middleware into a plugin
and then you will be loved by everyone and be famous
it should be pretty simple... just hash maniplution
Chad Robinson @crrobinson14 Feb 11 17:25
@gcoonrod I run AH almost exclusively in AWS
I don't see what you're reporting except when my code itself is high-workload.
Here's one of my API nodes from a recently deployed app. It gets a bit of usage, but CPU is almost 100% idle:
root@ip-10-0-164-50:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 487280 175808 953440 0 0 0 7 1 6 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 0 17 157 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 0 17 162 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 0 25 182 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 436 34 175 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 4 52 211 0 0 100 0 0
0 0 0 487272 175808 953472 0 0 0 0 15 154 0 0 100 0 0
0 0 0 487304 175808 953472 0 0 0 0 17 156 0 0 100 0 0
root 2111 0.0 0.0 85908 1416 ? Ss Feb11 0:00 nginx: master process /usr/sbin/nginx
www-data 2114 0.0 0.1 86668 2800 ? S Feb11 0:22 nginx: worker process
root 2120 0.0 0.5 62124 11684 ? Ss Feb11 0:08 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
root 2127 0.0 1.3 947612 28496 ? Sl Feb11 0:07 node /opt/newsrush/api/node_modules/.bin/actionhero startCluster --workerTitlePrefix api-
root 2142 0.0 0.8 284900 16904 ? Ss Feb11 0:02 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
www-data 2144 0.0 0.4 285992 8736 ? S Feb11 0:10 php-fpm: pool www
www-data 2145 0.0 0.4 285988 8576 ? S Feb11 0:10 php-fpm: pool www
root 2150 0.1 6.4 1304544 132780 ? Sl Feb11 2:26 /usr/bin/nodejs /opt/newsrush/api/node_modules/actionhero/bin/actionhero start
root 2159 0.2 6.4 1304432 131560 ? Sl Feb11 2:29 /usr/bin/nodejs /opt/newsrush/api/node_modules/actionhero/bin/actionhero start
I include a trimmed ps aux listing. I've got supervisord running Nginx on each node front-ending for a few legacy PHP scripts served by php-fpm, as well as actionhero in startCluster mode (box size is t1.medium, and it's starting two workers)
@evantahler I don't have a complete solution for the doubled-task thing but I did find a pattern. It starts happening after deployments. My deployments shut the entire node down and restart because I update a lot of stuff. (On my task nodes I'm not worried about hot reloads, and I need DB migrations to run and be fully confirmed before new code starts.) Is there a best practice / approved method of "stopping" a task node without messing things up?
Chad Robinson @crrobinson14 Feb 11 17:30
Every start/stop cycle adds a duplication of running the task. Here, after two restarts, it's gone from running every 60s to every 11s:
Feb 11 17:28:20 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexInterests', queue: 'low' }, result: 'Indexed 0 interests' }
Feb 11 17:28:20 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
Feb 11 17:28:31 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexInterests', queue: 'low' }, result: 'Indexed 0 interests' }
Feb 11 17:28:31 task1 default: info worker: job success low { workerId: 1, job: { class: 'indexUsers', queue: 'low' }, result: 'Indexed 0 users' }
I can get it back to 60s by doing a FLUSHDB before restarting, but I don't really want that to be the answer...
I don't understand the Redis data structures enough to understand what's going on.
Chad Robinson @crrobinson14 Feb 11 18:01
Whoah. I think I found it!
I guess the node-resque config changed from package to pkg? It was using fakeredis. PSA: Tasks do NOT like to run in clusters using fakeredis. :) It makes them run as many times as you have nodes (or the poll interval, whichever is the limiting factor)
Muhamed Krlić @l0oky Feb 11 20:36
LinKing
n
... Sorry on my phone. So linking other plugins in my plgugin is now possible?
Evan Tahler @evantahler Feb 11 22:55
@crrobinson14 YAY (and yah... That's a tough config change to make us ES6 compliant)
@synthmeat did that one for us
@l0oky sort of. I'll do a write up about some security study there tommorow.
Synth Meat @synthmeat Feb 11 22:59
evantahler: i'm still due .jscs
been busy these days :/
how in the world do you manage to do this with your job i'll never know
Kevin Hutchinson @hutchike Feb 11 23:00
yeah i just wanted to say thank you so much for making ActionHero - i was looking forever for a reliable scalable solid API-centric framework that just delivered the important bits, and did it well.
i’ve upgraded to 13.0.0 and am playing with it - if i see ways i can help i’ll open a PR
donnyhardyanto @donnyhardyanto Feb 11 23:26
hi @evantahler, how to make actionhero only using 1 taskProcessor only for queue, when using startCluster? I look at redis commander and I think it span taskProcessor for each core.
HQTestAccount @HQTestAccount Feb 11 23:40
Hello @evantahler, is it possible for me to detect the latency of the clients I have connected to my action hero socket server and save the average of this latency into redis?
Evan Tahler @evantahler Feb 12 08:01
@synthmeat Lint the hell out of the thing!
the trick is to have your job use the framework :D
that, and a lot of soda
@donnyhardyanto every actionhero instance in the cluster is homogenous (for scaling and failover reasons). You can't have one with a worker and the rest without. If you want that, have some workers in the cluster with no workers (./actionhero startCluster) with one set of configs, and then run another stand-alone instance ( ./actionhero start) with another
perhaps your config file is set up to look at process.env so you could do
WORKERS=no actionhero startCluster --workers=10 and WORKERS=yes actionhero startCluster --workers=1
dynamic configs are the way to go!
@HQTestAccount test account... what do you mean by latency? If you mean just how long the request takes to process within the actionhero server, sure. You can have a middleware that starts and ends a timer, and adds the response to data.connection.timeItTookToRender
if you want the whole latency from when the browser request started, network up, rendering, network down, JS redering
Evan Tahler @evantahler Feb 12 08:06
you'll need to do a few things, and aggregate the data in the browser (as it will be the only thing that knows the full clock time) and then make another request and post that back up to the server
you can certainly do it
Neil Craig @neilstuartcraig Feb 12 12:59
Hi @evantahler - are you online? I am just trying v13 and have hit a problem with plugin linking, could use some advice if possible please
I am building a plugin called ah-rice-ci-plugin and when i run npm run actionhero link —name ah-rice-ci-plugin i get:
```npm run actionhero link --name ah-rice-ci-plugin
my_actionhero_project@0.0.1 actionhero /Users/neil/test-apps/rice-ci
actionhero "link" "ah-rice-ci-plugin"
2016-02-12T21:01:46.792Z - info: actionhero >> link
2016-02-12T21:01:46.796Z - error: name (of the plugin to link) is a required input
npm ERR! Darwin 15.2.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "actionhero" "link" "--name" "ah-rice-ci-plugin"
npm ERR! node v5.4.1
npm ERR! npm v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! my_actionhero_project@0.0.1 actionhero: actionhero "link" "ah-rice-ci-plugin"
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the my_actionhero_project@0.0.1 actionhero script 'actionhero "link" "ah-rice-ci-plugin"'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the my_actionhero_project package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! actionhero "link" "ah-rice-ci-plugin"
npm ERR! You can get their info via:
npm ERR! npm owner ls my_actionhero_project
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! /Users/neil/test-apps/rice-ci/npm-debug.log
```
Neil Craig @neilstuartcraig Feb 12 13:04
(sorry, gitter appears not to support multi-line markdown code - i thought it did)
Muhamed Krlić @l0oky Feb 12 13:04
Interesting plugin name :)
Neil Craig @neilstuartcraig Feb 12 13:05
so my Q is, are the docs correct in stating to run: npm run actionhero link --name nameOfPlugin
ha ha @l0oky - it’s going to be pretty cool i think...
i have PoC’d it and it works OK so far…more details to follow when i am sure it works
building a CI to solve some issues we have at work building a lot of RPMs and also for my work at home testing my node projects against a load of node versions
Muhamed Krlić @l0oky Feb 12 13:06
Cool, i guess windows support he he
Neil Craig @neilstuartcraig Feb 12 13:06
ha ha
Muhamed Krlić @l0oky Feb 12 13:06
Seems to be the main issue with actionhero travis ci
Neil Craig @neilstuartcraig Feb 12 13:07
i am copying a lot of ideas from travis
and Travis Rice is a snowboarder - so the name popped into my mind
i think it’ll be more reliable and more flexible than travis and the idea is you can run it locally too
that’s the plan anyway...
Muhamed Krlić @l0oky Feb 12 13:08
Good luck! :+1:
Neil Craig @neilstuartcraig Feb 12 13:08
thanks :-)
i have actually done a lot of the basics already
just trying to make it work with AH 13
loving the idea of the plugins so far - i kinda made something similar myself a while back but this is better and is in core so win!
anyway, gonna dig through the AH src to see if i can find what i am doing wrong...
looks like the docs are wrong
Muhamed Krlić @l0oky Feb 12 13:12
Yeah, still figuring out how to nest ah plugins. So I can use DB orm plugin in my plugin - for example. Or atleast require the developer to add that dependent plugin
Neil Craig @neilstuartcraig Feb 12 13:12
bingo
got it
http://www.actionherojs.com/docs/#including-plugins says : npm run actionhero link --name nameOfPlugin but it needs the standard NPM — i.e. npm run actionhero link — --name nameOfPlugin
funny quirk of NPM, was my first guess after stopping being lazy and asking @evantahler
Muhamed Krlić @l0oky Feb 12 13:13
Yeah
Neil Craig @neilstuartcraig Feb 12 13:13
will send a PR on the docs in a mo
Muhamed Krlić @l0oky Feb 12 13:14
Neil Craig @neilstuartcraig Feb 12 13:19
anyone know how to contribute on docs? i have a memory of it being built from the master branch now…not sure if i am right or where to look though
Muhamed Krlić @l0oky Feb 12 13:20
Madter branch
Neil Craig @neilstuartcraig Feb 12 13:21
got it, thanks
would be good to have a docs page describing how to contribute to docs
Muhamed Krlić @l0oky Feb 12 13:21
On my phone now lol
Neil Craig @neilstuartcraig Feb 12 13:21
/site/source/docs
Muhamed Krlić @l0oky Feb 12 13:22
Just go to doc file you want to edit and click the pencil icon or whatnot top-right
It will fork ah for you and all that technical stuff
Neil Craig @neilstuartcraig Feb 12 13:26
ah, i have done it manually :-). just about to submit a PR
thanks though @l0oky
i’ll do that next time
Neil Craig @neilstuartcraig Feb 12 13:34
actually, @l0oky, i went with your method - that is a LOT cleaner than the old school fork, clone, push, PR method…thanks for the nudge :-)
Evan Tahler @evantahler Feb 12 14:30
nice guys!
(just got here)
So a quick of NPM is that argument thing, yes
you can also always invoke the acitonhero binary directly
ie: ./node_modules/.bin/actionhero link --nameOfPlugin
but npm is nicer as it does all the work of finding any wacky system paths you might have (like a global install)
@neilstuartcraig I think you actually forgot the "--" in your PR BTW evantahler/actionhero#765
@l0oky to answer your question about sub-plugins: I left that as "TODO" in the v13 release, as we can address this now without a major version bump (this would become v13.1.0 or something like that). Basically, you can have .link files in your plugins, for sure, and modules they would link would get loaded. If all the plugins needed are at the top level (meaning explicit dependancies in your package.json), everything works. However, we don't source the node_modules of plugins yet, because the user didn't list that as a valid/safe api.config.general.paths.plugin location. So if your plugin includes another plugin which the top-level package did not also include, it won't work
and that's a security issue we need to sort out.
Evan Tahler @evantahler Feb 12 14:35
like... I trust "my" node_modules to load plugins from, but I don't trust node_modules/random_plugin/node_modules... who knows whats in there?!
so right now, you can chain things in your plugins path, ie
api.config.general.paths.plugins = ['node_modules', 'node_modules/somePlugin/node_modules']
but it won't auto load that way
@neilstuartcraig I would love to hear your thoughts on what to do here, I know think about plugins a lot
actually... let me make a github issue about this so we don't loose this converstaion
one sec
ok! Lets talk here: evantahler/actionhero#766
Evan Tahler @evantahler Feb 12 17:00
first hotfix for V13 out!
https://github.com/evantahler/actionhero/releases/tag/v13.0.1
Fixes a bug in which actionhero startCluster would fail if the log directory was a symlink
donnyhardyanto @donnyhardyanto Feb 12 17:54
@evantahler, thank youfor explanation. By the way, I need manage the log files, so i add max file size to logger config
The first log filename was actionhero-192.168.104.2.log, which ok, and next one is actionhero-192.168.104.21.log, and the next one is actionhero-192.168.104.22.log.
Evan Tahler @evantahler Feb 12 17:59
you can lock those in with a fixed ID
donnyhardyanto @donnyhardyanto Feb 12 17:59
It might be better to use the format actionhero-192.168.104.2.1.log?
Evan Tahler @evantahler Feb 12 17:59
the api.id is used to set those names
so you can config it
by default, we just use the IP adddress
yours is changing :D
donnyhardyanto @donnyhardyanto Feb 12 18:00
I mean the same ip but the second log because the first one is full
The ip is 192.168.104.2
May be format actionhero-ipaddress.part?
So we can manage log better, like moving old log out of server regulary to save space in server?
Evan Tahler @evantahler Feb 12 18:08
why not just use log rotate?
comes with every linux distro
match path/to/logs/*.log
donnyhardyanto @donnyhardyanto Feb 12 18:12
Ok thanks. I will check the log rotate
Evan Tahler @evantahler Feb 12 19:45
here's a good guide https://support.rackspace.com/how-to/understanding-logrotate-utility/
donnyhardyanto @donnyhardyanto Feb 12 22:43
@evantahler thank you.
Neil Craig @neilstuartcraig Feb 13 05:35
Hey @evantahler - can you please point me to where a plugins config is in the api object (AH 13)? I can’t locate it - i thought it used to be api.config.plugins ?
Neil Craig @neilstuartcraig Feb 13 05:52
i am looking through the api object (console’d out from my plugins initialiser) and i can’t see my plugins config anywhere. i know my plugins config file is loaded as i can console.log from it. Any pointers very welcome...
Though i see the console.log() output 4 times in the boot logging:
Neil Craig @neilstuartcraig Feb 13 06:09
> actionhero start
***** plugin config loaded *****
***** plugin config loaded *****
2016-02-13T13:53:53.377Z - info: actionhero >> start
***** plugin config loaded *****
***** plugin config loaded *****
2016-02-13T13:53:53.530Z - notice: *** starting actionhero ***
My config file looks like this:
"use strict";
exports.default =
{
"ah-rice-ci-plugin": function(api)
{
console.log("***** plugin config loaded *****");
return
{
message: "rice,rice,baby"
};
}
};
i took this format from the example plugin but maybe i did something wrong?
ah, sorry, ignore me!
I did something wrong in my intialiser and it was preventing next()
i’ll crack on…
Found an issue in the example plugin config code, it sayd config files should be like this:
exports.default = {
"ah-sample-plugin": function(api){
return {
message: "Hello from the plugin's middleware"
};
}
};
But i found that doesn’t work, i get no config added to api.config
If i do this instead, it works:
"use strict";
exports.default =
{
“ah-sample-plugin":
{
message: “Good morrow!",
APIType: function(api)
{
return typeof(api);
}
}
};
@evantahler - shall i PR the sample plugin with the above or did i maybe miss something which would have made the sample plugin work on AH 13?
Evan Tahler @evantahler Feb 13 12:15
oh, I haven't updated the sample plugin (or the tutorials for that matter) in a long time. I'm sure they are out of date for v13
please help updated them!
@/all there's a good conversation going on about "nested plugins" over here evantahler/actionhero#766 If you care about this topic, please chime in!
OH! @neilstuartcraig remember that we no longer read config files from within plugins. the "link" action coppies them up to the top level project, and that's the only place we will read them from
Patrick Ahlgrimm @pahlgrimm Feb 13 12:38
I wanna use job schedules a lot and I am wondering if it is also possible to use Later.js instead of node-cron etc.?
Muhamed Krlić @l0oky Feb 13 12:40
You can use any module within actionhero. As long as node.js supports it..
Patrick Ahlgrimm @pahlgrimm Feb 13 12:42
What I can't figure is how all those "Timer" modules can work with node-resque!? Do you have any background infos? I am willing to read, so any link would suffice :)
Patrick Ahlgrimm @pahlgrimm Feb 13 13:16
HI, is it possible to change/create job schedules at runtime? From the documentation it seems that it is only possible to create "static" schedules.
Evan Tahler @evantahler Feb 13 16:29
Within the task framework, but you can define jobs on the fly if that is what you are asking
Johan Alkstål @johanalkstal Feb 14 01:43
So I just ran actionhero.cmd generate and I got an empty package.json file. Has this happened to anyone before?
Clarification: I got all the generated files and folders but the package.json is an empty file, so running npm install will of course not work.
Johan Alkstål @johanalkstal Feb 14 01:50
Okay, it worked the second time. No idea what happened but I blame my system. :)
Muhamed Krlić @l0oky Feb 14 01:51
Maybe it accidentally treminated the file generator
No errors?
Johan Alkstål @johanalkstal Feb 14 01:51
No, no errors during the generation.
Muhamed Krlić @l0oky Feb 14 01:52
Oh well, not that serious of an issue since it worked
But still that bug needs fixing
Johan Alkstål @johanalkstal Feb 14 01:53
Well not sure it was a bug
Anyway, time to keep learning what this actionhero can do :)
Muhamed Krlić @l0oky Feb 14 01:53
:smile:
Johan Alkstål @johanalkstal Feb 14 01:55
Hmm, not seeing anything on localhost:8080/public
Johan Alkstål @johanalkstal Feb 14 02:39
This message was deleted
Reason: process.env.PORT was defined...
Muhamed Krlić @l0oky Feb 14 02:47
Its better that you figure it out yourself by looking at the code, because the documentation is not finished yet, there is a lot to cover.. :smile:
If you really get stuck well help you
Johan Alkstål @johanalkstal Feb 14 02:48
No worries. :) New tech is always an exploration.
Muhamed Krlić @l0oky Feb 14 02:48
Or just ask us anything you want along the way
:)
Evan Tahler @evantahler Feb 14 12:55
@johanalkstal what version of node do you have? v4 or higher is required
I just updated the actionhero tutorial to v13. If you want to see what changes are needed => evantahler/actionhero-tutorial#16
Muhamed Krlić @l0oky Feb 14 13:01
Awesome! Thanks!
Evan Tahler @evantahler Feb 14 13:03
Basically, just copy over the config files
Muhamed Krlić @l0oky Feb 14 13:41
@pahlgrimm I find this module interesting, take a look https://github.com/rschmukler/agenda
Rong Shen @jacobbubu Feb 14 22:22
@evantahler Sorry for the late response. I’ve just joined this room.
Evan Tahler @evantahler Feb 15 00:59
Welcome!
Rong Shen @jacobbubu Feb 15 01:15
@evantahler Is there any thing you want me know? I’ve seen you metioned me before.
Dan @SDSWanderer Feb 15 02:41
Hi! It is possible to get merged ah config without starting web server?
Evan Tahler @evantahler Feb 15 08:18
@jacobbubu sorry, I don't remember now. But welcome!
@SDSWanderer do you just want to look at it? Try the console / repl
Evan Tahler @evantahler Feb 15 14:25
Another hotfix released: https://github.com/evantahler/actionhero/releases/tag/v13.0.2
Xananax @Xananax Feb 16 11:36
Hello, I'm trying to use actionhero with a React front-end. I'm not sure about how to go for integrating a webpack-babel preprocessing step on specific routes. I usually use express and call webpack programatically on the "/" route. I suppose it shouldn't be too different in actionhero, but the process is pretty involved, and I'd like to know if anyone has attempted a simple example or boilerplate before venturing there
Xananax @Xananax Feb 16 12:22
I'm reading the angular example and it helps a bit, but, if I may risk a criticism here, it tries to do too many things for someone who, like me, has 0 prior experience with actionhero; an example about "just" serving built javascript files and static html would be easier to parse
Evan Tahler @evantahler Feb 16 15:48
Good feedback! That example was meant to cover a ton of stuff at once... To show what a "full" app looks like
Have any specific questions?
Evan Tahler @evantahler Feb 16 17:27
@S3bb1 this dashboard https://github.com/S3bb1/ah-dashboard-plugin is getting really good! And it works for v13 (except the plugins)
Sebastian Dechant @S3bb1 Feb 17 11:28
thx @evantahler! i hope i can find more time to cleanup the actions code. And a new thing i'm currently working on is a visualization of the current actionhero topology with the redis stats (cluster, sentinels, ..) and the actionhero workers/cluster members
Krishna Glick @krishnaglick Feb 17 13:37
@evantahler I'm attempting to get the ah-dashboard-plugin working and I keep getting hit with 'unknown action or invalid apiVersion'. Is there any configuration I could have changed that would make the actions the plugin provides unavailable? I was able to get it working on a test project. https://github.com/krishnaglick/AH-Dashboard-Test
Krishna Glick @krishnaglick Feb 17 13:55
'queryRouting' and 'simpleRouting' were set to false. Works now.
Evan Tahler @evantahler Feb 17 17:20
cool
Muhamed Krlić @l0oky Feb 17 21:32
RoR founder forces his users to develop using his best practices. Which I agree on because from a new persons perspective, It's a life saver - a tutorail on how to build apps with this framework. Guidelines.
actionhero like RoR has many ways of acomplishing one task so I think It's best to follow a specific practice.
I think the practice will be clear once we establish a bit larger userbase...
Neil Craig @neilstuartcraig Feb 18 01:14
This message was deleted
This message was deleted
Muhamed Krlić @l0oky Feb 18 01:15
Oops i guess
Neil Craig @neilstuartcraig Feb 18 01:16
Sorry all - my kids were “doing some work” on my computer :-)
Muhamed Krlić @l0oky Feb 18 01:17
Cute one of them wrote 666 :p lol jk
Neil Craig @neilstuartcraig Feb 18 01:18
uh oh!
Muhamed Krlić @l0oky Feb 18 01:18
Not that it means something hahaha
Neil Craig @neilstuartcraig Feb 18 01:18
just got to find out what else they wrote on now...
Muhamed Krlić @l0oky Feb 18 01:19
Say hi to them for me?
:)*
I am not the only one that like kids right he he?
Muhamed Krlić @l0oky Feb 18 01:25
I remember when i used to call my dads business contacts using his phone haha... Luckily everything went smoothly :)
Neil Craig @neilstuartcraig Feb 18 01:33
ha ha, awesome. will do, they’re off riding their bikes in another part of the house now...
Evan Tahler @evantahler Feb 18 09:11
lol
Evan Tahler @evantahler Feb 18 13:43
v13.0.3 released
https://github.com/evantahler/actionhero/releases/tag/v13.0.3
just a check for cluster to detect flapping
Evan Tahler @evantahler Feb 18 15:09
one more!
https://github.com/evantahler/actionhero/releases/tag/v13.0.4
[Hotfix] Redis Subscription Updates
With some redis libraries (identified in ioredis), when using sentinels to connect to redis, it was possible to have an Unhandled rejection error. This update changes the order in which subscriptions happen in relation to the connection callback.
by @evantahler via evantahler/actionhero#774
Shawn Mclean @shawnmclean Feb 18 21:09
Hello, could I be pointed to some information about deploying to heroku using travis-ci?
Evan Tahler @evantahler Feb 18 21:56
as long as 'actionhero start' is linked to npm start, things should work fine on heroku
what do you want to know about travis?
perhaps this is what you are looking for ? https://docs.travis-ci.com/user/deployment/heroku/
Krishna Glick @krishnaglick Feb 19 06:30
@evantahler taskrabbit/node-resque#118
I threw up a PR for resque, and updating my PR for ActionHero. I think I have my bases covered.
Krishna Glick @krishnaglick Feb 19 06:40
updated my PR for AH*
Krishna Glick @krishnaglick Feb 19 10:11
Wh00t, open source!
Question: what generates the plugin.js config file? My cursory search couldn't find it.
Synth Meat @synthmeat Feb 19 12:05
dang, can't wait to get off netease/pomelo to evantahler/actionhero already
Patrick Ahlgrimm @pahlgrimm Feb 19 12:50
@evantahler Hi, you wrote that I can create jobs on the fly. But how? I wanna create jobs like I can do it with tasks. Is this possible?
Synth Meat @synthmeat Feb 19 16:58
oh hell yeah, it passed :)
Evan Tahler @evantahler Feb 19 17:03
@krishnaglick there is no plugin.js file any more!
@krishnaglick here's the new way things work in v13 http://www.actionherojs.com/docs/#including-plugins
@synthmeat why don't you like Pomelo? Whatever the reasons... you should tottaly write a blog post about it :D
@pahlgrimm I don't think I understand.... how is a job different from a task?
Synth Meat @synthmeat Feb 19 17:07
hey, i didn't want to synchronize my pull! but whatever, this should work too
i should start doing branches
@evantahler, only other thing code analysis tools are telling me is that i should move (not a lot, and not in particulary "bad" places) function created in loops, but that's about it. i'll be able to start on some actual features or something
*functions
Krishna Glick @krishnaglick Feb 19 22:36
@evantahler Oh, huh. Cool.
Patrick Ahlgrimm @pahlgrimm Feb 20 10:39
@evantahler I wanna use cron-like tasks, e.g. run a task at the end of a month at 2300h oder run a task every friday aso.
Sebastian Dechant @S3bb1 Feb 20 11:15
hmmm anyone tested this statement ? api.log(Depreciation warning: New versions of actionhero utilize 'pkg' instead of 'package' for redis! Please update your configuration.); ... on Windows AH crashes...
Evan Tahler @evantahler Feb 20 12:43
Change your config! @synthmeat changed the setting
@pahlgrimm use a tool like node-CRON to then enquque tasks at the frequency you want? There's a way detailed in the node-resque project which shows how to ensure only one member of the cluster is "master" so the job will only happen once
Patrick Ahlgrimm @pahlgrimm Feb 20 12:50
@evantahler Ah okay, from the docs I understood that only jobs are possible with cron-like. Tasks are enqueuedat oder enqueuedin... that consufesd me...
confused
Sebastian Dechant @S3bb1 Feb 20 13:05
Hm but @evantahler the whole ActionHero crashes when the logmessage should be logged. It fails with an illegal character, because there are singlequotes within the ``. When i change them to "" all works well
Krishna Glick @krishnaglick Feb 20 13:38
It's not escaping them correctly. God...
@S3bb1 What's your test scenario? Mine isn't crashing.
Synth Meat @synthmeat Feb 20 14:47
i'll fix. what did i mess up?
Krishna Glick @krishnaglick Feb 20 14:49
My PR to node-resque included a message with escaped ' and @S3bb1 says it's causing issues for him. I couldn't replicate with my (albeit) basic test case. Easiest way around would be to just throw in "" instead of '' and remove the \
Krishna Glick @krishnaglick Feb 22 10:16
There an upgrade guide for v13 anywhere?
Sebastian Dechant @S3bb1 Feb 22 11:20
I start the ActionHero on Win10 CMD or Powershell and the error is the following
C:\actionhero\initializers\redis.js:21
api.log(`Depreciation warning: New versions of actionhero utilize 'pkg'
^
SyntaxError: Unexpected token ILLEGAL
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at C:\actionhero\actionhero.js:133:42
at Array.forEach (native)
at C:\actionhero\actionhero.js:126:7
at C:\actionhero\node_modules\async\lib\asy
nc.js:718:13
Synth Meat @synthmeat Feb 22 11:29
@evantahler, what @S3bb1 reports is fixed in my pull request
https://github.com/synthmeat/actionhero/commit/d672a735b4382595ce7f49316952a0a5079dce1f#diff-360a00e7d5e798b90a0d919853355e10R21
Sebastian Dechant @S3bb1 Feb 22 11:31
ah, great haven't checked the complete bunch of the pull request then +1 for merge
Synth Meat @synthmeat Feb 22 11:31
it got introduced here evantahler/actionhero@6adc476
Krishna Glick @krishnaglick Feb 22 11:32
@S3bb1 Does it happen using normal cmd prompt?
Sebastian Dechant @S3bb1 Feb 22 11:33
yeah, happens in normal prompt. First i've tried it in Powershell and was thinking that the powershell was the issue, but in normal cmd it also crashes
Evan Tahler @evantahler Feb 22 11:39
I'm going to fix that now
stand-alone
Sebastian Dechant @S3bb1 Feb 22 11:40
Krishna Glick @krishnaglick Feb 22 11:40
I'd like to mention, not that I don't think it's worth fixing, that I can't get mine to error.
But I'm also not getting the error.
Sorry, depreciation warning.
Evan Tahler @evantahler Feb 22 11:43
It depends on the OS
Krishna Glick @krishnaglick Feb 22 11:43
I'm on Windows 10.
Evan Tahler @evantahler Feb 22 11:43
""` is not technicaly a valid quote
and it depends on your OS encoding
https://github.com/evantahler/actionhero/releases/tag/v13.0.5
Krishna Glick @krishnaglick Feb 22 11:44
^^
Evan Tahler @evantahler Feb 22 11:44
waiting for travis before pushing
Sebastian Dechant @S3bb1 Feb 22 11:45
which node version do you use @krishnaglick ?
Synth Meat @synthmeat Feb 22 11:45
evantahler: it's a bit more interesting that that though, it's something called template string
Krishna Glick @krishnaglick Feb 22 11:45
5.6
Synth Meat @synthmeat Feb 22 11:46
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Sebastian Dechant @S3bb1 Feb 22 11:46
yeah these literals exists ... but as ES6 feature
Evan Tahler @evantahler Feb 22 11:46
^ this
Synth Meat @synthmeat Feb 22 11:46
@S3bb1, out of interest, what node version are you on?
Evan Tahler @evantahler Feb 22 11:47
so if you don't have the right node version it falls back to the OS
Synth Meat @synthmeat Feb 22 11:47
yeah
Sebastian Dechant @S3bb1 Feb 22 11:48
we're currently on 0.12.10
Evan Tahler @evantahler Feb 22 11:48
oh! actionheo doesn't work on node <1.0 any more
that changed with v13
@S3bb1 upgrade time!
Sebastian Dechant @S3bb1 Feb 22 11:49
hm had no problems until now ^^
Evan Tahler @evantahler Feb 22 11:49
you'll run into query string issues with the router soon
and soon primus stops working with old versions too
that's why we upgrade
Sebastian Dechant @S3bb1 Feb 22 11:50
then i'll have to upgrade and have to revert my issue
sorry @krishnaglick and @evantahler
Synth Meat @synthmeat Feb 22 11:50
@S3bb1, you can use nvm, and then use all the versions you want!
Krishna Glick @krishnaglick Feb 22 11:51
Hey, ya live, ya learn!
Also +1 for nvm
Sebastian Dechant @S3bb1 Feb 22 11:52
will give it a try
Krishna Glick @krishnaglick Feb 22 12:25
Upgraded to v13, things seem to be functioning fine
Nikolay Kostyurin @JiLiZART Feb 23 10:34
what it can be, i use v13.0.5
2016-02-23T18:32:43.553Z - info: 0=*** rebooting due to config change (%s) ***, 1=/project/api/config/sequelize.js
/project/api/node_modules/actionhero/initializers/config.js:96
api.commands.restart.call(api._self);
^
TypeError: Cannot read property 'restart' of undefined
at rebootCallback (/project/api/node_modules/actionhero/initializers/config.js:96:19)
at /project/api/node_modules/actionhero/initializers/config.js:27:15
at nextTickCallbackWith0Args (node.js:452:9)
at process._tickDomainCallback (node.js:422:13)
Sebastian Dechant @S3bb1 Feb 23 11:00
hm i can reproduce this
seems that the issue comes from https://github.com/evantahler/actionhero/blob/master/initializers/config.js#L19
do they have changed somethin with watchFile ?
because it seems that it looses the api scope
at an earlier state
when i change the line to
fs.watch(file, function(curr, prev){
all works fine
@evantahler can you reproduce this too ?
when the callback is called, the api object contains strange values O_o
you can reproduce this, when a config file is changed
Evan Tahler @evantahler Feb 23 13:53
Good catch! Can you open an issue for it?
(GitHub)
Thanks!
karneaud @karneaud Feb 23 14:31
hello
was having a bit of a tough time understanding the usage of actionhero
waws hoping somone could explain a few things
tried to tour the chat demo that came with the package
but doesn't seem to be working
even after i creted a default room in the config
when i launch the server and head on over to the chat.html
it said i was connected but i
am not seeing any messages
karneaud @karneaud Feb 23 14:46
cool
Krishna Glick @krishnaglick Feb 23 16:10
When attempting to run tests using AH 13.5 I'm getting the following error: ' Uncaught Error: ENOENT: no such file or directory, mkdir 'C:\tmp\locale''
I changed it to './tmp/locale' and created the folders in my project but that gave me a different error.
" Uncaught TypeError: Cannot read property 'name' of undefined
at Object.api.tasks.loadFile (C:\myApp\node_modules\actionhero\initializers\tasks.js:34:38)"
I added i18n.js from a freshly generated project and added the paths:{} line to my api.js. Is there an additional thing I need to do?
Muhamed Krlić @l0oky Feb 23 20:35
Whats api.cache? Sounds interesting.. Is it like a list shared through redis server?
Evan Tahler @evantahler Feb 23 20:39
new version!
https://github.com/evantahler/actionhero/releases/tag/v13.1.0
List methods
by @evantahler via evantahler/actionhero#779
api.cache implements a distributed shared list. 3 simple functions are provided to interact with this list, push, pop, and listLength. These lists are stored in Redis, and cannot be locked. That said, a push and pop operation will guarantee that one-and-only-one copy of your data is returned to whichever application acted first (when popping) or an error will be returned (when pushing).
api.cache.push
Invoke: api.cache.push(key, data, next)
data must be serializable via JSON.stringify
Callback: next(error)
api.cache.pop
Invoke: api.cache.pop(key, next)
Callback: next(error, data)
data will be returned in the object form it was saved (array, object, string)
api.cache.listLength
Invoke: api.cache.listLength(key, next)
Callback: next(error, length)
length will be an integer.
if the list does not exist, 0 will be returned
Misc
Remove entries from startingChatRooms so new projects don't have to override this setting [evantahler/actionhero@692fde7]
Fix a shutdown bug for crashes when the task multiWorker has not yet started up [evantahler/actionhero@142a09e]
@l0oky exactly
@S3bb1 let me know when you get that issue posted up
seems important...
Muhamed Krlić @l0oky Feb 23 20:41
Yesss! Thx
Evan Tahler @evantahler Feb 23 20:41
@krishnaglick please send in a PR for changing / to path.sep. You windows users are killing me :p
Muhamed Krlić @l0oky Feb 23 20:41
Haha, too bad i switched to debian hehe
Evan Tahler @evantahler Feb 23 20:43
@l0oky right move!
actually @krishnaglick do that and figure out where the windows temp folder is... that is how to fix that test
Muhamed Krlić @l0oky Feb 23 20:44
Ikr, much easier to code and less distracting
Evan Tahler @evantahler Feb 23 20:44
@krishnaglick I also imagine that these tests are failing for you too https://github.com/evantahler/actionhero/blob/master/test/core/binary.js. Lots of unix commands in there :D
Sebastian Dechant @S3bb1 Feb 23 22:26
@evantahler should i send a PR or open an Issue ?
Sebastian Dechant @S3bb1 Feb 23 22:36
just openend issue :) evantahler/actionhero#780
Nikolay Kostyurin @JiLiZART Feb 24 00:30
Hi, is there any examples of passport usage with 13.x ? All examples i found too old.
Or how i can implement session auth, maybe exists more simple solutions?
Sebastian Dechant @S3bb1 Feb 24 01:45
@evantahler has written a session auth logic in his blog http://blog.evantahler.com/blog/authentication-with-actionHero-again.html . Maybe you have to change a bit to get it working with 13.X but it works :)
Nikolay Kostyurin @JiLiZART Feb 24 03:08
Thanks, i'll check
Krishna Glick @krishnaglick Feb 24 06:20
@evantahler They just bomb out instantly with "NODE_ENV' is not recognized as an internal or external command, operable program or batch file."
I honestly would love to run a unix-based system but I do some C# development right now so it's not an option. :(
Evan Tahler @evantahler Feb 24 07:35
@krishnaglick can you write a general "get the tests working on Windows" issue on GitHub and list all the erors?
Krishna Glick @krishnaglick Feb 24 07:44
Ooooh boy. I'll give it a shot.
Evan Tahler @evantahler Feb 24 08:07
Thanks. I can't test it, so I have to rely on folks like you to know what's up.
Krishna Glick @krishnaglick Feb 24 08:46
Yeah, I'll see what I can do. :)
What do you use for CI in ActionHero?
Evan Tahler @evantahler Feb 24 09:02
Travis.
Krishna Glick @krishnaglick Feb 24 09:03
cool, I'll look into it, thanks :P
Evan Tahler @evantahler Feb 24 10:34
@krishnaglick good starts!
Krishna Glick @krishnaglick Feb 24 11:15
Good starts?
Evan Tahler @evantahler Feb 24 11:49
On your pull requests!
Krishna Glick @krishnaglick Feb 24 11:51
Oh, thanks! I'm glad I can get paid to work on an open source stack. Means I get to use work time on things like this. :P
Evan Tahler @evantahler Feb 24 11:56
I'm happy folks like you are paid to work on this as well!
Sebastian Dechant @S3bb1 Feb 24 11:57
"sharing is caring" :)
Kevin Hutchinson @hutchike Feb 24 17:07
I’ve got the weirdest bug right now - I enquee a single task and it gets processed exactly twice by a single worker (10 ms of delay between the processing)
any ideas?
i just did resque-cli monitor and it appears it gets pushed onto the Redis queue twice by my “enqueue” method call
Kevin Hutchinson @hutchike Feb 24 17:13
apologies for the question - i think i’ve found the bug :-)
Evan Tahler @evantahler Feb 25 08:50
@hutchike cool.
Evan Tahler @evantahler Feb 25 09:18
New Release
https://github.com/evantahler/actionhero/releases/v13.1.1
Bugfixes:
Solves an issues when using developer mode and a config file changing would cause the server to crash rather than reboot.
by @evantahler and @S3bb1 via evantahler/actionhero#783
Fixes the locale/i18n tests for windows
by @krishnaglick via evantahler/actionhero#782
Evan Tahler @evantahler Feb 25 12:32
Anyone have comments on evantahler/actionhero#784 ?
Evan Tahler @evantahler Feb 25 16:42
anyone, anyone? bueller? bueller?
LLFourn @LLFourn Feb 25 17:11
o/ I'm just seeing if actionhero is appropriate for my needs. I need to return "text/plain" from my API (sometimes) rather than JSON. I tried setting the header in data.connection.rawConnection.responseHeaders which worked. Is there a better way?
I also need to do it for tcp socket api
LLFourn @LLFourn Feb 25 17:20
ah it doesn't look like there's an opt out for socket.js https://github.com/evantahler/actionhero/blob/master/servers/socket.js#L82
Evan Tahler @evantahler Feb 25 17:37
Yep, that's the web way (and you can crate helpers for that kind of thing in a middleware). No one has asked for output transformation for TCP yet. It can certainly be added.
A custom serializer method name which could be set (data.connection.rawConnection.serializer) or something like that
LLFourn @LLFourn Feb 25 18:03
@evantahler cool. Should I make a github issue?
or a pull request if that's preferred :)
Evan Tahler @evantahler Feb 25 18:04
Certainly a PR :)
LLFourn @LLFourn Feb 25 18:04
ok I'll give it a shot thanks
LLFourn @LLFourn Feb 25 18:18
@evantahler should the custom serializer work for other server types as well or just socket?
now that I'm looking at it a high level custom content type field somewhere could tell the server how to serialize in a general way and it could actually set the Content-type header in the case of web.js
anyway I'll implement the serializer thing for all of them for now and see what you think
Chad Robinson @crrobinson14 Feb 25 18:44
Anybody have a good/standard technique for detecting and retrying jobs that are NOT failed (no exception thrown) but are hung (next never fired)?
Evan Tahler @evantahler Feb 25 22:41
@crrobinson14 no... that kind of thing should never happen! Put a timeout around the whole job and force-fail it after a minute or similar
then you can use the normal job retry logic
I've done that before when interfacing with particularly laggy third-parties
Lea Anthony @leaanthony Feb 25 23:36
Anyone know where the worker log filenames are set? It would be great if we could change that so multi-tailing makes more sense.
Evan Tahler @evantahler Feb 26 00:10
it's set in the config => https://github.com/evantahler/actionhero/blob/master/config/logger.js#L33
the pid.title is sourced from any number of places: https://github.com/evantahler/actionhero/blob/master/initializers/pids.js#L26 => https://github.com/evantahler/actionhero/blob/master/initializers/id.js
@leaanthony you should set a picture
Synth Meat @synthmeat Feb 26 00:20
@evantahler, ever considered splitting client and site to another repo?
*repos
Chad Robinson @crrobinson14 Feb 26 06:31
@evantahler I've had a LOT of trouble with the tasks layer in my current project, with tasks that get "stuck" and just stop running. I've tracked it down to two issues. Tasks that throw exceptions just need maintenance - it's not obvious from the docs that a best practice is to run either retryAndRemoveFailed or removeFailed on an interval, as a regular task.
But tasks can "hang", too. I've had this a lot with Algolia and network issues in that layer while indexing records in the background for search functionality.
When this happens, you have a task marked in Redis that is SCHEDULED (marked "Delayed") but with a timestamp way in the past. It's not in "failed".
To be honest, this is only some guesswork. I don't actually know what's going on with these tasks, I'm just assuming this is the cause because it's logical.
All I know is I have this indexUsers task that just stops running after a few days. It's not in the failed queue, it's marked as scheduled by node-resque if I inspect the Redis records by hand, but it just doesn't run any longer.
In fact, I have one stuck right now if you can give me some advice on what to look for in these Redis records.
Chad Robinson @crrobinson14 Feb 26 06:38
There's nothing in the logs indicating an error or exception. I see resque:timestamps:{"class":"indexInterests","queue":"low","args":[{}]}with a value of 1456457600 which is 10:25pm last night. This task is supposed to run every 60 seconds.
The workers themselves seem to be OK - they're processing other scheduled tasks.
In the same "low" queue as well, so it's not queue-related.
Krishna Glick @krishnaglick Feb 26 07:10
On the off chance anyone here is using RabbitMQ/Wascally, I'm having trouble with it and AH tests.
LeanKit-Labs/wascally#123
Krishna Glick @krishnaglick Feb 26 08:08
Figured it out. Initializer was making a next() call before a piece of async config was finished. T.T
Evan Tahler @evantahler Feb 26 11:06
@krishnaglick nice.
@crrobinson14 that sucks.
So if your workers are still running other jobs in the same queue, I hate to say it, but that really does point to something wrong with your job
Evan Tahler @evantahler Feb 26 11:12
@crrobinson14 here's an example of a very defensively programed job:
var task = {
name: 'doAThing',
description: 'I will to a thing',
queue: 'default',
plugins: [],
pluginOptions: [],
frequency: 0,
run: function(api, params, next){
var timeout = 1000 * 60;
var done = false;
var jobTimeout = setTimeout(function(){
done = true;
next(new Error('Job Timeout!'));
}, timeout);
api.doSomeAsyncThingThatOftenCrashes(params, function(error, data){
if(done === true){
codeToRollBack(params, next);
}else{
clearTimeout(jobTimeout);
done = true;
next(error, data);
}
});
}
};
exports.task = task;
Chad Robinson @crrobinson14 Feb 26 11:15
I ended up just making an initializer that periodically iterates all recurring tasks and calls scheduledAt. If it finds one scheduled too far in the past (an expiration window) it calls delDelayed and enqueueRecurrentJob on it. This seems to have resolved it.
I'm not arguing that tasks shouldn't be as defensive as possible - but it's unreasonable to expect them to be perfect, particularly if you're dealing with third party libraries like the Algolia SDK (as is the case here).
Actually, I believe these were tasks that were running during deployments. What does AH do on SIGTERM to tasks that are running at that moment?
Especially if they have async network calls running?
It seems to me that it shuts down even if they're running.
Evan Tahler @evantahler Feb 26 11:20
it should allow them to finish, with a window
Chad Robinson @crrobinson14 Feb 26 11:20
How is that window determined?
These are fairly long-running tasks - a minute or two in some cases.
It's document search indexing.
Batches of "dirty" records being sent to the back-end for processing.
Evan Tahler @evantahler Feb 26 11:21
https://github.com/evantahler/actionhero/blob/master/bin/methods/start.js#L102
ahh!
let me figure out where the times come from
actionhero start allows a slow stop
THERE IT IS => https://github.com/evantahler/actionhero/blob/master/bin/methods/start.js#L10-L13
30s is the default
Chad Robinson @crrobinson14 Feb 26 11:23
Oh interesting. It looks like it just runs the timeout but doesn't log anything if it hits it.
Maybe I'll add some logging around here to try to confirm if this is the spot.
Evan Tahler @evantahler Feb 26 11:24
that would be a great update... and adding that note to the docs
are you able to take it?
Chad Robinson @crrobinson14 Feb 26 11:24
That's my real struggle, actually - I don't actually know for sure what the issue is. I'm just guessing. Nothing is logged - the task just stops being re-enqueued.
Yeah, I can take it.
But give me a few days to debug further and make sure this is the actual vector.
Evan Tahler @evantahler Feb 26 11:24
hopefully this is it! that makes a lot of sense
Chad Robinson @crrobinson14 Feb 26 11:25
Yeah, it does seem to align. I've been doing LOTS of deployments lately, and these are very long-running tasks.
Evan Tahler @evantahler Feb 26 11:27
good luck
new release!
Chad Robinson @crrobinson14 Feb 26 11:27
:)
Evan Tahler @evantahler Feb 26 11:27
This one may be breaking depending on your use of resque/tasks
From node resque: taskrabbit/node-resque#121
This is a (potentially) breaking change
When comparing this project to ruby resque, we had been using the wrong value (key pointer) in the delayed job queue. When running this project alongside a ruby scheduler, it was possible for older timestamp key set entries not to be deleted. This update corrects the difference.
When upgrading to this new version, it is very likely you will end up with queue artifacts that are not properly deleted, which have the potential to break plugin's behaviors. This will require manual intervention to remove keys that match resque:timestamps:*. Before upgrading to this version, the safest path forward is to drain all of your queues and schedules first, using the previous version of node-resque.
As far as actionhero is concerned, this issue would only effect you if your application uses scheduler and api.tasks.enqueueAt or api.tasks.enqueueIn directly. This is why we have made this a minor version update.
This is now actionheo v13.2.0
Chad Robinson @crrobinson14 Feb 26 11:28
Cool. That won't break me personally - I'll try it out
Evan Tahler @evantahler Feb 26 11:28
however, no jobs will be lost in the migration... but you may end up with some extra timestamp artifacts in redis
Krishna Glick @krishnaglick Feb 26 13:17
@evantahler How do you use Travis CI? Just through a private git repo?
Oh, it ONLY supports git. Damn.
Evan Tahler @evantahler Feb 26 16:09
@krishnaglick what do you use if not git?
Evan Tahler @evantahler Feb 26 16:27
@crrobinson14 evantahler/actionhero#787 I did it for you :D
Krishna Glick @krishnaglick Feb 26 17:39
@evantahler I am not the architect, merely the developer. Stash was chosen before I was brought on board. I'm looking at TeamCity, Bamboo, and Jenkins atm.
Evan Tahler @evantahler Feb 26 17:42
Bitbuckst
Bitbucket still uses git?
Krishna Glick @krishnaglick Feb 26 17:45
Bitbucket is stash. It's git-based, but not github. From my research it looked like it requires github.
Did I miss something crucial? :s
Evan Tahler @evantahler Feb 26 19:49
I guess not :( https://docs.travis-ci.com/user/customizing-the-build/#What-git-Repository-Providers-can-I-use
Evan Tahler @evantahler Feb 27 11:36
@crrobinson14 merged evantahler/actionhero#787 into master
Patrick Ahlgrimm @pahlgrimm Feb 28 11:06
Hi, I am playing around and can't disable the developmentMode with false. It keeps running in developmentmode? What am I missing? Thanks
Evan Tahler @evantahler Feb 28 11:12
That's a problem! Can you open a github issue so we can check it out.
Evan Tahler @evantahler Feb 28 12:39
evantahler/actionhero#788 is the issue
Neil Craig @neilstuartcraig Feb 29 00:01
Hi all. I am working on a project at the moment and i need to implement an enforcement of maximum duration for actionhero tasks. I’m totally happy to do that on my own, in my project, but wondered whether anyone has a way to do it already or (@evantahler) would be interested in me creating a PR to add this functionality? I’m thinking of it being a new option on a task enqueue/schedule which would default to do nothing (so would not break current behaviour) but would allow a max duration in tasks (in msec) and would use next(err) to exit the task with an error something like new Error(“Maximum task duration time of X exceeded) if the task took too long to run. I didn’t see any way to do that currently but maybe i missed something.
Sebastian Dechant @S3bb1 Feb 29 01:20
@neilstuartcraig , @evantahler wrote a sample before which you can use... this task will terminate after 60 seconds, when the "doSomeAsyncThing" doesnt return a response
var task = {
name: 'doAThing',
description: 'I will to a thing',
queue: 'default',
plugins: [],
pluginOptions: [],
frequency: 0,
run: function(api, params, next){
var timeout = 1000 * 60;
var done = false;
var jobTimeout = setTimeout(function(){
done = true;
next(new Error('Maximum task duration time of '+timeout+'ms exceeded'));
}, timeout);
api.doSomeAsyncThing(params, function(error, data){
if(done === true){
return;
}else{
clearTimeout(jobTimeout);
done = true;
next(error, data);
}
});
}
};
exports.task = task;
Neil Craig @neilstuartcraig Feb 29 02:41
@S3bb1 - that’s pretty much what i was thinking. I just wondered if it was something @evantahler is interested in as core functionality - seems like a light-weight and useful utility but also as you’ve demonstrarted. is very simple in user land
Sebastian Dechant @S3bb1 Feb 29 02:42
but i think that should be a feature of node-resque instead of actionhero
Neil Craig @neilstuartcraig Feb 29 04:36
ah OK, i see…this is my first time using AH tasks so i don’t have much experience with it. i guess AH might just need to pass the timeout through as an arg/param then
Sebastian Dechant @S3bb1 Feb 29 05:02
or you can define a config parameter in your config file and access the config via api.config
Neil Craig @neilstuartcraig Feb 29 05:22
yep, true @S3bb1 - i just kinda felt like it’d be a nice built-in for AH
Evan Tahler @evantahler Feb 29 07:26
@neilstuartcraig I do not want something like that built in... It's too danget
dangerous.
Handling the rollbacks is especially hard. And ORM dependant
Checkout how node-resque handles pluguns
You can mix this in pretty much automatically if you want
Neil Craig @neilstuartcraig Feb 29 07:29
OK cool, thanks @evantahler - i’ll do that
Krishna Glick @krishnaglick Feb 29 09:28
@evantahler W/ TravisCI, are you using Node 4.1 or are you hosting locally and using a different version?
Evan Tahler @evantahler Feb 29 10:45
@krishnaglick check the travis config file https://github.com/evantahler/actionhero/blob/master/.travis.yml
Chad Robinson @crrobinson14 Feb 29 13:26
@neilstuartcraig We implemented this with a setInterval that just iterates running tasks looking for any that might be "stuck".
We have predictable runtimes in our tasks - they're long-lived but at most 60-90 seconds. So we look for any tasks that have been stuck longer than 5 minutes and kill/reschedule those. We're not worried about duplicates or overlaps. They're all things like RSS feed collectors so we just coded them to tolerate this possibility.
This maintenance task plus Evan's recent adjustment to how shutdown is handled (if a long-running task holds the node "open" too long) have resolved our cluster task scheduling issues.
@evantahler Did a recent change remove grunt.js?
We used to use grunt console a lot to poke around from the CLI. Looks like this binary is no longer included.
Evan Tahler @evantahler Feb 29 18:13
Yep. Grunt is the worst, and removed in V13
Actionhero console
That's the replacement command just built into the binary.
Faster and more cross-platform
Neil Craig @neilstuartcraig Mar 01 01:58
Thanks @crrobinson14 - i think @S3bb1’s proposal would work best for me in the immediate sense (i am running docker instances via tasks) but i should probably also check for “stuck” tasks. :-)
I was also going to ask if anyone has any recommendations in another thing i need to do…i want to stream the stdout of my docker containers (which i can expose as a var in my task) from a task runner node (not necessarily on the same server as the web front end) to the web front end server (an API HTTP/WS server) and then to the requester. Is redis/AH pub/sub the best?
Chad Robinson @crrobinson14 Mar 01 07:20
@neilstuartcraig That sounds to me like something AH itself doesn't do directly but all of its support layers can help enable. I'm not really sure what "running docker instances via tasks" means - you aren't spawning child procs directly from task scripts, are you? That sounds like an invitation for a memory leak because task workers themselves are externally controlled by AH in ways you don't have a lot of visibility into / control over. That said, there's no reason you can't access the Redis and other layers AH also uses for pubsub/other mechanics. I do it all the time.
If you look at the AH docs you can see there's a SUPER useful doCluster method that executes a funcition cross-cluster, RPC-style. I've used it for example to send WebSocket messages to clients logged in "somewhere" on the cluster, wherever they are.
@evantahler Yeah, nothing against removing Grunt from AH core although I still like it myself. I was just confirming what the new mechanism was.
Neil Craig @neilstuartcraig Mar 01 07:34
@crrobinson14 - no, not spawning threads or anything like that - it’s all running in-process. I’ll send you all a link on here when i’m at a decent stage, it’s an interesting project (i think).
Thanks for the advice on messaging - that sounds ideal! i’ll check it out tonight.
Evan Tahler @evantahler Mar 01 16:59
@neilstuartcraig the best way to do what you want is to make a custom logger that sends all the log messages to a chat room via say
You don't need doCluster here
Check out Winston custom loggers
And then any WS client can join the log room :)
I might have that logger around somewhere... I did this a while back for some project
Chad Robinson @crrobinson14 Mar 01 22:41
To be sure. But honestly @evantahler I think you sell doCluster a little short in the Features list and docs. Used well it's incredibly useful when you have to deal with WebSocket clients. Cross-cluster RPC takes a bit of jiggering to do well and the fact that you've already at least minimally dealt with things like security (the server token) is a big shortcut.
I've built all kinds of things with it. AH's tight integration with Redis on more than one level: chat room mechanics, cross-cluster RPC, and task management, plus taking it to the next step by thinking through edge cases like fakeredis for special-case needs, is a HUGE selling point for me.
"It just works."
Sebastian Dechant @S3bb1 Mar 02 00:54
@neilstuartcraig i've done this in this way in the dashboard plugin:
// add the logMessages Room
api.chatRoom.add("logMessages");
// create a listener for winston module to broadcast the logmessage to the room
api.logger.on('logging', function (transport, level, msg, meta) {
// check if the console transport is active
if(transport.name === 'console'){
// broadcast the logmessage to the chatRoom
api.chatRoom.broadcast({room: "logMessages"}, "logMessages", new Date().toISOString() + ' - ' + level+": "+msg+JSON.stringify(meta));
}
});
first i create a chatRoom for the logMessages and after that i listen on the 'logging' event of Winston. This will fire for each log line and each transport configured. When the event data is sent to the "console" transport, i'll emit it to the chatroom
Krishna Glick @krishnaglick Mar 02 06:46
Is there a reason actionheroClient.js randomly newlines the ending semi-colon on line 2874?
Chad Robinson @crrobinson14 Mar 02 07:40
https://gist.github.com/crrobinson14/1750f3f6e8c0a941751b
Hey folks, just sharing something I'm playing with here. I have been doing a lot with asyncawait which uses Node fibers to clean up nested callbacks and promise chains. This works super well in ActionHero but still creates a lot of boilerplate because you have to wrap each action template runner with the async wrapper and pass its results back to AH.
Chad Robinson @crrobinson14 Mar 02 07:46
In the Gist above I have a simple block of code that summarizes what I do to make this more generic, as well as an example action cleaned up as a result of this. I call this from an initializer when AH starts.
There is a modest performance "hit" over traditional nested-callback style programming, but if you're already using Bluebird for Promise style handling this is only slightly worse on the benchmarks (most of the hit was promises themselves, and Bluebird is pretty fast).
Evan Tahler @evantahler Mar 02 11:32
Well, the chat stuff uses doCluster under the hood... So that's great :)
@crrobinson14 that's crazy! I guess that's how to implement domains "correctly". Note that that in no way will work on Windows ;)
@krishnaglick the generated JS Is different for everyone. Share a gist
@S3bb1 that's a great simple way to get at that.
Evan Tahler @evantahler Mar 02 11:37
You should publish a blog post. Please.
Sebastian Dechant @S3bb1 Mar 02 11:38
I've no blog ^^
Evan Tahler @evantahler Mar 02 12:28
Gist? Medium? Something?
Should we make a blog for stuff like this on actionhero js.com?
Would anyone else contribute?
Krishna Glick @krishnaglick Mar 02 12:29
What would end up there, tips and tricks or something?
Evan Tahler @evantahler Mar 02 13:20
well... I want to encourge folks to write about actionhero. tips, ticks, bugs, anything
the more content out in the world, the better
some folks have a personal or a company blog, and that's great
for folks like @S3bb1 who have neither, I want to provide him a place to publish
I guess the normal flow would be to source content from other already existing blogs (cross-publication)
but I'll only do it if people want to write :D
Krishna Glick @krishnaglick Mar 02 14:11
I think part of the issue is because ActionHero is so light, most AH-based stuff is basically node-based stuff.
Lea Anthony @leaanthony Mar 02 14:27
@evantahler I think a blog would be great
Sebastian Dechant @S3bb1 Mar 02 20:43
A blog in actionherojs.com sounds great!
in = on
salles @sallespro Mar 03 03:52
@neilstuartcraig another option for aggregated logging is fluentd+elasticsearch, maybe this is usefull for you https://github.com/openfirmware/docker-fluentd-elasticsearch
Evan Tahler @evantahler Mar 03 07:33
Totally unrelated: logstash vs fluentd. Any opinion?
Muhamed Krlić @l0oky Mar 03 07:42
These are some kind of business intelligence tools?
Logstash has a nice front page video :)
Evan Tahler @evantahler Mar 03 07:43
Log avgrigators
*aggrigators
Muhamed Krlić @l0oky Mar 03 07:44
Data crunching? :)
salles @sallespro Mar 03 07:44
@evantahler @l0oky i would prefer a "dry" logstash, but the link i included uses fluentd because of the elastic search plugin
the whole idea is to aggregate the logs and browse with elastic search https://github.com/lmenezes/elasticsearch-kopf
Chad Robinson @crrobinson14 Mar 03 08:35
Evan, I admit I don't use Windows but why wouldn't this work there, specifically? Asyncawait just uses Node Fibers which I believe was ported to Windows a few years ago
I shared it as a Gist because I wasn't sure it was worthy of a PR - it's kind of an opinionated approach. But I've fallen in love with the pattern myself. My actions are half the length they use to be, and it significantly cuts down on boilerplate-closure }).then(function() { code in promise chains.
Kerim Incedayi @cevatkerim Mar 03 12:54
Is there any working examples of passport integration with ah? I am not having much luck getting it to work... :worried:
Evan Tahler @evantahler Mar 03 15:51
@crrobinson14 you probably should write a blog post :D
and cool! I didn't know they made it to windows
@cevatkerim https://www.npmjs.com/package/ah-passport-plugin made by @neilstuartcraig
Kerim Incedayi @cevatkerim Mar 03 18:05
@evantahler that doesn't work on ah 12+
Evan Tahler @evantahler Mar 03 18:06
ahh
still should be a good refrence point though
Kerim Incedayi @cevatkerim Mar 03 18:07
yeah I've been trying to get that to work but I keep getting stuck.. :/
Nikolay Kostyurin @JiLiZART Mar 04 02:16
how can i enable jsonp support in my action?
Sebastian Dechant @S3bb1 Mar 04 04:18
jsonp support is by default enabled
Krishna Glick @krishnaglick Mar 07 07:42
Is anyone using Docker w/ Actionhero (or Node, really)
salles @sallespro Mar 07 08:09
yep
Krishna Glick @krishnaglick Mar 07 08:10
How easy (or difficult) was it to get it setup and running, and what CI solution do you use with it?
salles @sallespro Mar 07 08:11
codeship and strider for CI
esay setup for standard apps
websockets / vpn dependent tricky setup
i totally recommend
Krishna Glick @krishnaglick Mar 07 08:13
No websockets (maybe later date) or vpn stuff atm. I like the idea but implementing it is a little odd since I've never done this kinda thing before. ^^
salles @sallespro Mar 07 08:13
go for it ! https://github.com/smebberson/docker-alpine/tree/master/alpine-nginx-nodejs
this is a tiny image with the whole kit inside, good for single apps
Krishna Glick @krishnaglick Mar 07 08:15
I'll look around, thanks!
Evan Tahler @evantahler Mar 07 10:16
Neat
Synth Meat @synthmeat Mar 07 14:15
yay
Chad Robinson @crrobinson14 Mar 08 07:28
I've started into Docker twice in the last year, both times with AH - once with Firetalk.com and once with NewsRush.com. Both times, I backed away. Docker is SUPER interesting and I'm getting a lot of mileage out of it in Dev. But unless you're ready for Mesos or Kube, it really falls short in terms of tooling for production environments. It's getting there, ALMOST there - but I personally feel it's still a little immature.
If you have a dedicated DevOps team it makes a lot more sense.
salles @sallespro Mar 08 08:02
@crrobinson14 that’s the exact antecipation one needs in order to fully profit of its maturity, living its infancy
Evan Tahler @evantahler Mar 08 10:50
@crrobinson14 my experience exactly.
Also, I wouldn't yet trust a data volume with HA on it, so you still need to manage your databases Etc in the traditional way
Give it a year
Chad Robinson @crrobinson14 Mar 09 08:42
Yeah, that's the general conclusion of a lot of the DevOps guys I like to hang around with (read: lurk) as well. Without the additional components of service discovery, scheduling, etc. containerization doesn't add quite as much value in production. You can see it's ABOUT TO, but I think it's still realistically 6-9mo out. Docker Swarm was still marked as "Not for production use" as recently as December - that's only 12 weeks ago.
Krishna Glick @krishnaglick Mar 09 09:40
So, what's the point of using docker to compartmentalize your code if you can just install your dependencies locally & remotely, and just push the code around? I thought the idea was to wrap your code + dependencies in a single image and push that around.
salles @sallespro Mar 09 09:43
@krishnaglick a different node version is for me very helpful
Krishna Glick @krishnaglick Mar 09 09:43
To test on multiple versions or..?
salles @sallespro Mar 09 09:43
so it’s about a little more than code + dependencies towards the environment you have for runtime
another issue is load balancing, or moving your app from one node to another. Using different linux distros in a single node without vm overhead.
Krishna Glick @krishnaglick Mar 09 09:47
So what kind of dependencies do you include in your image besides Node?
salles @sallespro Mar 09 09:48
databases, link to other running containers ( micro services )
Krishna Glick @krishnaglick Mar 09 09:49
So you do include Postgres?
salles @sallespro Mar 09 09:49
your application can become a composition of services that are ebasically tied together with dockers
i only include a database in an image if its purpose is tightly coupled with the application, a very app specific function.
Another option is to have a postgre docker linked to your app
and probably other ones as well
Krishna Glick @krishnaglick Mar 09 09:51
You mean have a docker for postgres?
salles @sallespro Mar 09 09:52
that’s the idea
Krishna Glick @krishnaglick Mar 09 09:55
Okay. My app's still in its infancy so I can go pretty much any direction with deploy/CI kinda stuff. However it needs to be easily updatable when it gets to production. Docker seems like a good way to do it but there's a lot to learn it looks like.
salles @sallespro Mar 09 09:58
a few cloud providers ( google and heroku ) have docker based offerings to host your apps with pretty easy to use tools.
heroku https://blog.heroku.com/archives/2015/5/5/introducing_heroku_docker_release_build_deploy_heroku_apps_with_docker
goole
https://cloud.google.com/container-engine/
Krishna Glick @krishnaglick Mar 09 10:04
I think I'm having an issue understanding how to get all these pieces working together. My app requires Node (AH, npm, etc), Postgres, and RabbitMQ. I think it's be cool to have all three running in their own containers but my question is where do I throw the config or files necessary to allow me to setup a workable environment with a few commands (docker build -t myApp .) kinda deal, as well as push all or individual containers to update different parts of the app when/where necessary. And on top of that, how to tell the Node instance that PG_HOST is at a specific IP address. I'm sure these have been solved but I don't know what direct to really start looking in.
salles @sallespro Mar 09 10:07
it;s all in a single file Dockerfile and the way you give option when you docker run… your image. start using it, you’ll see all your questions answered, step by step.
Krishna Glick @krishnaglick Mar 09 10:09
Roger. I'm currently hacking away at my Dockerfile. I've had some success but this is gonna take time. Oh well. :)
salles @sallespro Mar 09 10:11
this has everything you need
https://github.com/heroku-examples/node-asciify
Krishna Glick @krishnaglick Mar 09 10:20
Digging around, ty!
salles @sallespro Mar 09 10:45
dig deep, and catch a breath.
Evan Tahler @evantahler Mar 09 17:37
The AhHa moment for me was noting that with docker, everything ends up in the EVN. So your Postgres config file for instance just has a line like "host = process.env.POSTGRES-host" or similar. When you link docker containers (or use service discovery like etcd) everything is eventually exposed via env
Also remember ports change. You might be running Postgres inside the container on port 3306. But it can be exposed as a toally new port in the "real" world
Evan Tahler @evantahler Mar 09 22:35
Alright Windows people... try the test suite now!
evantahler/actionhero#790
Sebastian Dechant @S3bb1 Mar 09 22:36
\o/ thx @evantahler
Synth Meat @synthmeat Mar 09 23:54
@evantahler, so, about uppercased prototypes, want me to uppercase them all? i've made exceptions for few that weren't
Evan Tahler @evantahler Mar 10 07:29
Might as well be consistent.
Synth Meat @synthmeat Mar 10 10:40
okie doke
Muhamed Krlić @l0oky Mar 10 12:12
Hello @evantahler Whats Queue Bus? looks interesting..
Evan Tahler @evantahler Mar 10 15:24
stop spying on me!
it's something else crazy you can do in the redis ecosystem
original post about it http://tech.taskrabbit.com/blog/2013/09/28/resque-bus/
some updates http://tech.taskrabbit.com/blog/2015/04/02/queue-bus/
basically, you can use resque's queues to do fan-out subscriptions of events
rather than just run-one and work the job
Muhamed Krlić @l0oky Mar 10 15:26
Hahaha no its all notifications, my phone keeps vribrating with new emails evey minute
donnyhardyanto @donnyhardyanto Mar 10 22:30
Hello @evantahler , if in cluster mode started by startCluster in multi-core system, if we have task with maxTaskProcessors 1 and create periodic task (every 1 seconds). The task is reading db and do some updates, so sometime it takes more than 5 seconds to complete, will the task is guarantedd to be only running max 1 thread in all times? So we will not have multiple thread/process doing the same task in one time?
peterkingsbury @peterkingsbury Mar 11 05:52
@evantahler Hey Evan! An app I'm working on needs to be able to read from cache then write in a single uninterruptable operation; will the cache lock/unlock/checkLock methods be useful in this case for a single-node AH cluster?
Krishna Glick @krishnaglick Mar 11 07:08
Protip: Don't have a build and an image property in your docker-compose.yml
Evan Tahler @evantahler Mar 11 07:16
@donnyhardyanto the way periodic tasks work is that there is only one record for the job in the queue, and once it's done, it will re-enquque itself. This means that no matter how many taskProvessors you have (clustered or otherwise) only one version of a job will be running at once in your deployment
@peterkingsbury can you provide some more detail? The locking stuff is more about keeping a specific entry in the cache safe in an envruonmet where many activities might me trying to modify it (multiple Actionhero servers for example)
@krishnaglick oh?
Krishna Glick @krishnaglick Mar 11 07:26
It doesn't like that. But if you have version: 2 and use services: <things> then it won't actually warn you .
MarkPareja @MarkPareja Mar 11 11:09
How can i delete a job queue ?
MarkPareja @MarkPareja Mar 11 11:46
essentially I need to be able to delete a task queue from with in my app, I just dont see a method to do so.
Evan Tahler @evantahler Mar 11 16:51
the "formal" answer is just to delete the key in redis. It will look like resque:queue:name_of_queue
you are looking for the del method
https://github.com/evantahler/actionhero/blob/master/initializers/tasks.js#L113-L115
peterkingsbury @peterkingsbury Mar 11 17:54
@evantahler Sure. Previously I had tried (in a Promise-managed for-loop) to read from cache, update a value, then write the data payload back to cache. During the loop, the reads were occurring sequentially as the state of the cache at the end of the loop only represented the final read-then-write operation.
Evan Tahler @evantahler Mar 11 18:02
Ah! Then, yes. That's exactly the sort of thing the locks can help with!
peterkingsbury @peterkingsbury Mar 11 18:02
ok thats great, cos i'm writing the managing function now :)
donnyhardyanto @donnyhardyanto Mar 13 22:04
@evantahler , the startCluster seem to state worker number wrongly, after number 11
Evan Tahler @evantahler Mar 15 09:46
wierd!
the count is write but the names are wrong
... but it is totally reproducable!
@donnyhardyanto issue created evantahler/actionhero#791
Muhamed Krlić @l0oky Mar 15 10:25
Does that issue have something to do with node.js non-blocking features? :D
Evan Tahler @evantahler Mar 15 11:59
No? Just lazy counting logic
Muhamed Krlić @l0oky Mar 15 13:14
Does data.connection.sendMessage have a callback? I need to send a message to a specific chatroom member and then return action response. How am I going to do that without a callback?
donnyhardyanto @donnyhardyanto Mar 15 16:36
Hi @evantahler, when using startCluster, usually after 1 night (there is no transaction on night, only periodic task per 2 second), the actionhero stop responding to request that use redis related actionhero API (api.cache) or tasks (which use redis also if I understand correctly). The action that not use redis related API is serve successfully. I am using Actionhero 13.2.1 and node 4.2.6 on Debian
After I stop the cluster and start the cluster again, it is running correctly again, until 1 night again. I have to restart the cluster every morning.
Evan Tahler @evantahler Mar 15 20:58
@l0oky check the code! I think no
@donnyhardyanto share your task. Can't help you without the details.
donnyhardyanto @donnyhardyanto Mar 15 21:31
This message was deleted
exports.default = {
tasks: function(api){
return {
// Should this node run a scheduler to promote delayed tasks?
scheduler: true,
// what queues should the taskProcessors work?
queues: ['*'],
// Logging levels of task workers
workerLogging : {
failure : 'error', // task failure
success : 'info', // task success
start : 'info',
end : 'info',
cleaning_worker : 'info',
poll : 'debug',
job : 'debug',
pause : 'debug',
internalError : 'error',
multiWorkerAction : 'debug'
},
// Logging levels of the task scheduler
schedulerLogging : {
start : 'info',
end : 'info',
poll : 'debug',
enqueue : 'debug',
reEnqueue : 'debug',
working_timestamp : 'debug',
transferred_job : 'debug'
},
// how long to sleep between jobs / scheduler checks
timeout: 2000,
// at minimum, how many parallel taskProcessors should this node spawn?
// (have number > 0 to enable, and < 1 to disable)
minTaskProcessors: 1,
// at maximum, how many parallel taskProcessors should this node spawn?
maxTaskProcessors: 1,
// how often should we check the event loop to spawn more taskProcessors?
checkTimeout: 500,
// how many ms would constitue an event loop delay to halt taskProcessors spawning?
maxEventLoopDelay: 5,
// When we kill off a taskProcessor, should we disconnect that local redis connection?
toDisconnectProcessors: true,
// What redis server should we connect to for tasks / delayed jobs?
redis: api.config.redis,
};
}
};
processReservationQueueTask.js
Thanks @evantahler, those above is the task config and the task.
Krishna Glick @krishnaglick Mar 16 06:44
@evantahler Do you use docker to run your app's dependencies? I've got mine setup to host postgres and rabbitMQ but Travis doesn't seem to like 'docker-compose up'
Evan Tahler @evantahler Mar 16 10:52
@donnyhardyanto I hate to say it, but that's a very confusing task. You are using a lot of synchronous case statements to then do asynchonus things (queries). How does that work at all? How do you catch your rollbacks? I'm going to bet that you have an unresolved promise/callback in there somewhere that is just hanging. Consider using a flow controll library like https://github.com/caolan/async. I'll be that will help a lot.
Also... what are you making? Looks like a parking reservation system? cool.
@krishnaglick nope, sorry
and I'm pretty sure travisci (the open source one) won't boot more than one docker image
Muhamed Krlić @l0oky Mar 16 15:28
Thumbs up for solving the worker bug. I guess worker sorting was the issue?
Evan Tahler @evantahler Mar 16 15:59
@l0oky yeah... string sort vs # sort
one day we'll have typed variables...
Muhamed Krlić @l0oky Mar 16 16:03
Thats going to speed up things a bit :)
Evan Tahler @evantahler Mar 16 16:03
New release!
v13.2.2: Fixing tedious things
Code Style Guide
We now have an actionhero code style guide! When working on Actionhero, be sure that your IDE/Editor has support for eslint. We also now have contribution guides for the project: https://github.com/evantahler/actionhero/blob/master/CONTRIBUTING.md. I don't get the Lavendarman reference, but the file is full of good advice anyway!
A huge thank you to @synthmeat for doing this very tedious upgrade!
by @synthmeat via evantahler/actionhero#778
Public files with spaces in the name
Fixed a bug which prevented static files with spaces in their names from being sent to clients
by @bluesunrise via evantahler/actionhero#789
Windows
Oh windows... why did you have to do everything differently than every other operating system? Even your path delimiters (\ vs /) go the wrong way. Anyway... the Actionhero test suite now runs on windows!
There is one section that doesn't run (testing the Actionhero binary), as it requires a lot of "shelling out"
by @evantahler via evantahler/actionhero#790
Fix worker IDs in Actionhero cluster
Fixed a bug which would report and log actionhero worker names with repeat IDs when running startCluster with a worker count above 10.
by @evantahler via evantahler/actionhero#794
Misc
Documentation Updates:
Style and Linting (@synthmeat)
NODE_ENV vs developmentMode
... and more!
https://github.com/evantahler/actionhero/releases/v13.2.2
Thanks @synthmeat and @bluesunrise
Muhamed Krlić @l0oky Mar 16 16:08
Speaking of performance, maybe someday parts of actionhero will go c++?
(I am pretty bad at c++)
(Too many low level stuff to consider while developing)
Evan Tahler @evantahler Mar 16 17:04
Why?
Don't always assume a laguage (at runtime) is faster https://github.com/felixge/faster-than-c
donnyhardyanto @donnyhardyanto Mar 16 18:42
This message was deleted
@evantahler. I am using deasync alot. So code look like synch. All function/method is async, unless it has -Sync ending in function name. I change value
donnyhardyanto @donnyhardyanto Mar 16 18:49
I change value the task config toDisconnectProcessors to false, and since running from yesterday afternoon to this time (around 21 hours) has no error/hang. So if there is no error later, it might because the tcp connection limit is reached because long timeout nature of TCP. I am keep praying this the case.
So toDisconnectProcessors=false is like using db connection pool?
Evan Tahler @evantahler Mar 17 07:25
Not really. That tells the workers to stay connected to redis when they are done rather than disconnect and reconnect... Which I would have guessed to create more connection problems. Check your redis logs and the redis max connections setting.
Muhamed Krlić @l0oky Mar 17 08:05
I write say terminalRoom test and get as a response connection not in this room
Muhamed Krlić @l0oky Mar 17 08:11
This message was deleted
Ok, I put 'terminalRoom': {} in startingChatRooms: {} at config/api.js
Muhamed Krlić @l0oky Mar 17 08:17
At startup it says ensuring existance of terminalRoom but in socket when I write say terminalRoom test, I get an error response connection not in this room (terminalRoom)
Hmm, ahh, roomAdd has to be used to connect the client first
Muhamed Krlić @l0oky Mar 17 09:08
What does Error: you have too many pending requests really mean (image)? This is the action
Evan Tahler @evantahler Mar 17 13:24
@l0oky https://github.com/evantahler/actionhero/blob/master/config/api.js#L21-L22
yep... you have to "join" the room first :D
Muhamed Krlić @l0oky Mar 17 13:50
I think my action is not ending at all :(
It never finishes the request
Evan Tahler @evantahler Mar 17 18:18
Look for unresolved callbacks. Log stuff in all your middleware in debug so you can see what's going on.
Muhamed Krlić @l0oky Mar 18 07:02
Yes, solved It. Returning something in action run function is quite a bad idea. But I did a blunder, It seems more natural to type return new Error('blabla'); then next(new Error('blabla')); :D
Chad Robinson @crrobinson14 Mar 21 11:59
That's common if you're used to Promise-style semantics.
Muhamed Krlić @l0oky Mar 21 12:40
Oh yeah that reminds me :D
I tend not to replace callbacks with promises.. ( not all of them )
Evan Tahler @evantahler Mar 21 12:52
to each his own :S
Evan Tahler @evantahler Mar 21 13:52
New Version!
https://github.com/evantahler/actionhero/releases/tag/v13.2.3
Updates
Primus updated to v5x
i18n updated to v0.8.x
Bugs
Fixed a bug wherein the server's logging locale could not be changed from en
peterkingsbury @peterkingsbury Mar 21 18:56
@evantahler Hey Evan, have you ever heard of/used redlock? https://github.com/mike-marcacci/node-redlock
Evan Tahler @evantahler Mar 21 20:03
No... Neat!
Want to replace our locks with it?
It seems pretty similar but adds quorum checks
peterkingsbury @peterkingsbury Mar 21 20:28
it seems like it's promising, not yet sure whether it's a functionality-dupe or not
peterkingsbury @peterkingsbury Mar 21 20:33
also seems like it's ioredis-compatible out of the box, which is nice mike-marcacci/node-redlock#1
Aayush Kapoor @xeoneux Mar 22 14:26
Hi
Muhamed Krlić @l0oky Mar 22 14:26
Hello :)
Aayush Kapoor @xeoneux Mar 22 14:26
Is ES2015 support on the way? :smile:
Muhamed Krlić @l0oky Mar 22 14:27
Babel?
Aayush Kapoor @xeoneux Mar 22 14:28
Won't there be some changes that have to be made to the API?
Or will it work out of the box?
Muhamed Krlić @l0oky Mar 22 14:30
@evantahler will know the answer. I am not quite sure what ES2015 actually is :D
Does it have something to do with babel?
Aayush Kapoor @xeoneux Mar 22 14:32
Yes and No
No: ES2015 is the latest version of JavaScript. It has nothing to do with Babel.
Muhamed Krlić @l0oky Mar 22 14:33
evantahler/actionhero#590 Babel.js is not supported out of the box. You'll have to do some changes.
Aayush Kapoor @xeoneux Mar 22 14:33
Yes: Babel compiles ES2015 code to older versions. It has EVERYTHING to do with ES2015.
Hope that makes it clear :smile:
Muhamed Krlić @l0oky Mar 22 14:34
Thanks I'll do more research on that.
evantahler/actionhero#692
Aayush Kapoor @xeoneux Mar 22 14:36
That's something different, but thanks for the help!
I'm building a backend for a mobile application that requires WebSockets in some parts and follows REST API for the others...
Muhamed Krlić @l0oky Mar 22 14:38
Then you'll love actionhero
Aayush Kapoor @xeoneux Mar 22 14:38
I guess, actionhero will do the job neatly but I'm unsure about the authentication part...
Muhamed Krlić @l0oky Mar 22 14:38
:D multi-transport feature does it justice
What kind of authentication?
Aayush Kapoor @xeoneux Mar 22 14:40
User authentication... Login through Google/Facebook using OAuth
Muhamed Krlić @l0oky Mar 22 14:41
There is a passport plugin for actionhero
Aayush Kapoor @xeoneux Mar 22 14:41
I'm not entirely sure of how it'll work because I've been using Firebase all this while and now I need something that scales well and provides good framework for running expensive server code
I'll check...
Muhamed Krlić @l0oky Mar 22 14:42
https://github.com/neilstuartcraig/ah-passport-plugin
Not yet for production use though
:D
Aayush Kapoor @xeoneux Mar 22 14:42
Yeah
Hasn't been updated in a long time!
Muhamed Krlić @l0oky Mar 22 14:46
So ES2015 is the new de-facto standard huh :D
Aayush Kapoor @xeoneux Mar 22 14:46
Yup
Evan Tahler @evantahler Mar 22 15:20
All of JS is forward compatible. So yes, You can write your code using ES6+ style and Actionhero won't hold you back
... And Babel is happy with Actionhero now too
Aayush Kapoor @xeoneux Mar 22 15:24
Thanks @evantahler
Is there a starter with pre-configured babel for actionhero?
Evan Tahler @evantahler Mar 22 15:26
https://github.com/keifukuda/actionhero-es6/blob/master/package.json might be a good pointer
but no, I don't use it
it's all in 'user land' and up to you :D
actionhero itself is old vanilla JS
no prommises, no iterators...
Aayush Kapoor @xeoneux Mar 22 15:27
Hmm... I'll try building a webpack starter
Also, as a beginner, I got a little confused with ./node_modules/.bin/actionhero generate
Then I found out that installing it globally and running actionhero generate did the same thing
Evan Tahler @evantahler Mar 22 15:29
that it does
Aayush Kapoor @xeoneux Mar 22 15:29
Why not use it globally by default?
Evan Tahler @evantahler Mar 22 15:29
in general its bad practice to install things globally (Gulp/Grunt broke this pattern) because you can't have more than one version isntalled
*installed
Aayush Kapoor @xeoneux Mar 22 15:30
Oh...
Got it
Evan Tahler @evantahler Mar 22 15:30
using the executabile from within node modules lets you have more than one version system wide
and follows the general NPM patern of "keep eveyting you need within the project"
who knows where "-g" installs live on your system
even on OSX, there are like 3 places they could be stored, depending on how you installed NPM and node
Aayush Kapoor @xeoneux Mar 22 15:31
Hmm... That's good thinking
It will always be there in node_modules/.bin
Is ES2015 support out of the box expected in future releases?
I'm not sure if I'll be successfully be able to create a webpack config...
But I'll try
Thanks @evantahler
Evan Tahler @evantahler Mar 22 22:01
Is till don't know what you mean by ES2015 support. JS is forward compatible. Anything that works now will work with a future spec.
If Actionhero uses generators and whatnot internally only maters in a backwards compatible envruonmet.
Nick Collins @ndcollins Mar 23 00:14
out of curiosity, is there any reason why "use strict”; hasn’t been added to the top of the templates for actions, initializers, tasks, etc.? Particularly if one is wanting to use ES6+ including that is generally a good idea, is it not?
Krishna Glick @krishnaglick Mar 23 06:04
Node's native ES6 stuff doesn't allow for things like 'let' without strict mode.
Chad Robinson @crrobinson14 Mar 23 06:55
Looks like we all dodged a bullet today. Thanks for not using left-pad @evantahler, lol.
Or Babel.
Krishna Glick @krishnaglick Mar 23 06:56
Que?
Chad Robinson @crrobinson14 Mar 23 06:57
https://medium.com/@azerbike/i-ve-just-liberated-my-modules-9045c06be67c#.dycctj4xg
THere's a sh*tstorm going on in NPM right now because a HUGE pile of apps and modules just broke.
https://github.com/azer/left-pad/issues/4#issuecomment-200060983
Krishna Glick @krishnaglick Mar 23 06:59
Ha... Well, I'm utilizing babel but can always dump 'use strict'; everywhere instead.
Chad Robinson @crrobinson14 Mar 23 07:00
This guy gets a legal thread over a TINY module he maintains, it's literally like 15 lines of code. So he pulls it and unpublishes the NPM, totally fed up. Well, Babel apparently relies on the SPECIFIC version (ahem, ActionHero used to do this too with other modules...) and a thousand people suddenly can't install or update anything.
Muhamed Krlić @l0oky Mar 23 07:01
:(
Chad Robinson @crrobinson14 Mar 23 07:01
Be very careful today installing ANYTHING because supposedly some bad characters already jumped on the package name and posted some bad things.
Muhamed Krlić @l0oky Mar 23 07:02
We'll they're not gonna win without a fight
Chad Robinson @crrobinson14 Mar 23 07:03
https://gist.github.com/tlrobinson/05d2354a71f5491d2f5a
Damn, sorry, didn't realize that would expand.
Muhamed Krlić @l0oky Mar 23 07:03
does babel have something to do with this?
Chad Robinson @crrobinson14 Mar 23 07:03
Somebody posted a Gist of all the modules that depend on it in some way. It's a pretty big list.
Babel, yes. Babel had a dependency on a specific version of left-pad.
Hard-coded to one version.
Krishna Glick @krishnaglick Mar 23 07:04
Ya know, I was against my company's policy of tracking node_modules but here's an instance where it's actually useful.
Muhamed Krlić @l0oky Mar 23 07:04
he he he
Chad Robinson @crrobinson14 Mar 23 07:04
Just a warning, a bunch of other @azer packages just got name squatted on npm by who knows who so watch out when updating your package.json files.
Just going to re-post the list of packages (from @azer's blog post) to help us validate our builds: https://gist.githubusercontent.com/azer/db27417ee84b5f34a6ea/raw/50ab7ef26dbde2d4ea52318a3590af78b2a21162/gistfile1.txt
Is there a possibility that these packages could turn malicious, and everyone who relied on them is in big trouble after their next npm install? :fearful:
npm install, run as root, can run arbitrary commands. So be VERY careful intslling anything today.
Two things that may be useful for anybody with issues today.
https://github.com/gajus/bundle-dependencies
This neat little toolkit lets you bundle up known-good package combos into a single new NPM. I use it to make deploys faster and safer on my servers in Production, but it would also help here.
https://medium.com/@Rich_Harris/how-to-not-break-the-internet-with-this-one-weird-trick-e3e2d57fee28#.7u0ecj7id
Also, this guy has a pretty obviously biased (but that doesn't make it wrong) writeup that talks through how bundling would help resolve it as well.
Muhamed Krlić @l0oky Mar 23 07:07
Is this the "Kik" guy that sued azer?
he has Kik package
https://www.npmjs.com/package/kik
Chad Robinson @crrobinson14 Mar 23 07:07
No, it's somebody else and there isn't a lot of information on it. It's just that reference above, and the conversation shifted to other topics.
Krishna Glick @krishnaglick Mar 23 07:07
Kik is a messaging app for phones.
Chad Robinson @crrobinson14 Mar 23 07:08
Different Kik, I think, but either way it's not related to ^^^
Muhamed Krlić @l0oky Mar 23 07:08
right
https://www.npmjs.com/package/not-kik lol
This project has nothing to do with kik. It's not kik, and never will be. But it has kik in its name. What now, NPM Inc.?
Chad Robinson @crrobinson14 Mar 23 07:09
lol
Anyway, it's an unqualified (and maybe already resolved?) comment in the stream about the real issue, but still worth doing some due diligence. if you do any npm install activity today, particularly as root, be VERY careful.
Muhamed Krlić @l0oky Mar 23 07:10
https://www.npmjs.com/package/kik-rtards
Thanks for the heads up :)
Is there a npm clone?
Like I can make my own npm
Krishna Glick @krishnaglick Mar 23 07:13
Is it safe to update actionhero? I've had some issues w/ node-resque and was planning up upgrading today.
Evan Tahler @evantahler Mar 23 07:24
I don't think a god our dependencies were effected
I don't think that any of our dependencies were effected.
Autocorrect.
Krishna Glick @krishnaglick Mar 23 07:26
Noice. I'll upgrade and see. I'm on Windows so I think it's less likely to ruin me.
Chad Robinson @crrobinson14 Mar 23 07:26
Correct. Assuming you trust ME, I've already confirmed the dependency tree for ActionHero and it's not affected.
Evan Tahler @evantahler Mar 23 07:27
The Internet is all just one big web of trust anyway. I trust Digicert... Why not @crrobinson14 ?
Chad Robinson @crrobinson14 Mar 23 07:27
lol
Evan Tahler @evantahler Mar 23 07:28
Regarding USE STRICT, I guess we can add it to all the templates... Add a PR for it!
Chad Robinson @crrobinson14 Mar 23 07:28
The "deepest" part of the tree that I see is AH relying on i18n because it has a pretty good chunk of dependency-tree of its own. But it's so useful, it would be silly to do something else. It's hardly a "risk"
Krishna Glick @krishnaglick Mar 23 11:46
I'd like to mention that node-resque is no longer crashing on application end after I updated.
Muhamed Krlić @l0oky Mar 23 12:00
Evan Tahler @evantahler Mar 23 16:32
lol
it's the little things
Matt @mattrepublic Mar 25 13:36
Perhaps I'm missing this in my searches, but is there a documented way to pass json objects to a parameter? Use case is adding data to a Firebase post. The only thing I could roughly find was a GitHub ticket from a couple years ago. Thanks!
Krishna Glick @krishnaglick Mar 25 13:38
Pass in as a standard function parameter?
Matt @mattrepublic Mar 25 13:40
@krishnaglick Can you give me a quick (generic) example of what you are referring to? I haven't tried that before using a REST api.
Krishna Glick @krishnaglick Mar 25 13:48
function myFunc(data){} ?
I don't understand your question I guess
Matt @mattrepublic Mar 25 13:57
No worries. I'm sending data to AH from different sources, mostly php based.
So sending something from curl might be (newContent object crashes AH):
curl -X "POST" "http://localhost:8080/api/firebaseAdd" \
-H "Content-Type: application/json" \
-d "{\"newContent\":{\"updating\":\"aCat\",\"user\":\"Bob\"},\"path\":\"https://devname.firebaseio.com/test1/\",\"apiVersion\":1}"
Without the object newContent everything else works. Question is what's the right way to pass an object data over curl? *should have clarified that to begin with.
Evan Tahler @evantahler Mar 25 15:48
@mattrepublic what version of actionhero are you on? It seems fine to me in the master branch
'use strict';
exports.action = {
name: 'json',
description: 'json',
blockedConnectionTypes: [],
outputExample: {},
matchExtensionMimeType: false,
version: 1.0,
toDocument: true,
middleware: [],
inputs: {
key: {
required: true,
formatter: function(s){ return String(s); }
},
data: {
required: true,
}
},
run: function(api, data, next){
data.response.key = data.params.key;
data.response.data = data.params.data;
next();
}
};
curl -v -X POST -H "Content-Type: application/json" -d '{"key":"theKey","data":{"thing":"stuff"}}' http://localhost:8080/api/json
{
"key": "theKey",
"data": {
"thing": "stuff"
}
}
Matt @mattrepublic Mar 25 18:41
@krishnaglick ... ahh you mean function inside AH. Sorry, I misinterpreted.
@evantahler ... it certainly does work, it must have been the way I was using a function inside the run.
Thank you both!
donnyhardyanto @donnyhardyanto Mar 28 04:14
Hi @evantahler, I am thinking generating QR code image on the fly in action and return it as a action response. How do we send back image data using data.response?
donnyhardyanto @donnyhardyanto Mar 28 07:11
I mean as a stream not using file.
Muhamed Krlić @l0oky Mar 28 07:23
Does ah-sequelize-plugin work for you guys?
api.models seems to be undefined for some reason
Evan Tahler @evantahler Mar 28 08:06
@l0oky did you make a models folder?
Muhamed Krlić @l0oky Mar 28 09:21
Yup
sequelize-cli initialized that directory as well as some models
These somewhat hidden errors are quite common in actionhero
Maybe more verbose debug logging would help? I mean I don't know what's the issue I have done all the steps 'correctly'.
Muhamed Krlić @l0oky Mar 28 09:26
Does 'use strict'; this affect the discovery of models?
That shouldn't be the issue api.model should be at least an empty object not undefined. hmm
Muhamed Krlić @l0oky Mar 28 09:32
I'll try and make a 'debug' mode logging for actionhero where It will log everything It does. Because for example If an initializer just skips (next()) and an unexperienced actionhero developer ( like me ) doesn't see the issue, at least the verbose debug logging would help.
Nick Collins @ndcollins Mar 28 09:50
has anything changed in the last few releases as to how you “enable’ tasks? I changed the minTaskProcessors to 2, and set scheduler to true, but I’m not seeing anything in the console output showing task workers having been started. Also, when I trigger a task from an action to test it, I am not seeing any output from my task or any breakpoints triggered.
Muhamed Krlić @l0oky Mar 28 09:58
@evantahler Why is logger not hardcoded into api object? It would greatly simplify logging at all levels/priorities ..
I would have to use console.log(); to log some stuff before logger.js initializer.. I am sure there is a valid reason, maybe to follow the actionhero initializer pattern?
Evan Tahler @evantahler Mar 28 10:49
lots going on here!
First, @donnyhardyanto: here's how to send an arbitrary stream to a client https://gist.github.com/evantahler/6d29412d27b7db9875da
The tricky part for the web server is that you actually need to know the content-length ahead of time, as the headers need to be sent before the body content
@l0oky honestly, I don't use that plugin any more. other people maintain it now. whatever problem you have, I would open an issue for it
for me, I just use this simple file most of the time:
var path = require('path');
var fs = require('fs');
var Sequelize = require('sequelize');
module.exports = {
loadPriority: 100,
startPriority: 100,
initialize: function(api, next){
api.models = api.models || {};
var sequelizeInstance = new Sequelize(
api.config.sequelize.database,
api.config.sequelize.username,
api.config.sequelize.password,
api.config.sequelize
);
api.sequelize = {
sequelize: sequelizeInstance,
connect: function(callback){
var dir = path.normalize(api.projectRoot + '/models');
fs.readdirSync(dir).forEach(function(file){
var nameParts = file.split("/");
var name = nameParts[(nameParts.length - 1)].split(".")[0];
api.models[name] = api.sequelize.sequelize.import(dir + '/' + file);
});
if(api.config.sequelize.toSync === true){
api.sequelize.sequelize.sync().then(function(){
callback();
}).catch(function(error){
callback(error);
});
}else{
callback();
}
},
test: function(callback){
api.models.user.count().then(function(data){
api.log('connected to sequelize');
callback();
}).catch(function(error){
api.log('cannot connect to sequelize:', 'crit');
api.log(error, 'crit');
callback(error);
});
},
query: function(q, type, callback){
if(typeof type === 'function'){ callback = type; type = null; }
if(!type){ type = api.sequelize.sequelize.QueryTypes.SELECT; }
api.sequelize.sequelize.query(q, {type: type}).then(function(users){
callback(null, users);
}).catch(callback);
},
};
next();
},
start: function(api, next){
api.sequelize.connect(function(error){
if(error){ return next(error); }
api.sequelize.test(next);
});
}
};
models look like this:
Evan Tahler @evantahler Mar 28 10:55
var bcrypt = require('bcrypt');
var bcryptComplexity = 10;
module.exports = function(sequelize, DataTypes){
return sequelize.define("user", {
'email': {
type: DataTypes.STRING(191),
allowNull: false,
validate: { isEmail: true },
},
'phoneNumber': {
type: DataTypes.STRING(191),
allowNull: true,
},
'passwordHash': {
type: DataTypes.TEXT,
allowNull: true,
},
'passwordSalt': {
type: DataTypes.TEXT,
allowNull: true,
},
'firstName': {
type: DataTypes.STRING(191),
allowNull: false,
},
'lastName': {
type: DataTypes.STRING(191),
allowNull: false,
}
}, {
indexes: [
{
unique: true,
fields: ['email']
}
],
instanceMethods: {
name: function(){
return [this.firstName, this.lastName].join(' ');
},
updatePassword: function(pw, callback){
var self = this;
if(!pw){ return callback(); }
var salt = bcrypt.genSalt(bcryptComplexity, function(error, salt){
if(error){ return callback(error); }
bcrypt.hash(pw, salt, function(error, hash){
if(error){ return callback(error); }
self.passwordHash = hash;
self.passwordSalt = salt;
callback(null, self);
});
});
},
checkPassword: function(pw, callback){
var self = this;
bcrypt.compare(pw, self.passwordHash, callback);
},
apiData: function(api){
return {
id: this.id,
teamId: this.teamId,
email: this.email,
phoneNumber: this.phoneNumber,
firstName: this.firstName,
lastName: this.lastName,
companyName: this.companyName,
requirePasswordChange: this.requirePasswordChange,
};
}
}
});
};
@ndcollins seems fine to me! You still enqueue stuff with api.tasks.enqueue('nameOfTask', ags, next);
your config file should look like this now: https://github.com/evantahler/actionhero/blob/master/config/tasks.js
Evan Tahler @evantahler Mar 28 11:00
@ndcollins do you have all the new logging options?
Muhamed Krlić @l0oky Mar 28 11:06
Thanks!
Nick Collins @ndcollins Mar 28 11:46
@evantahler I do. To upgrade my project I generated a new project, then moved my initializers, tasks, custom configs, and actions over, then manually moved my configurations for the core configurations from the old files to the new, to make sure I had everything I needed
Evan Tahler @evantahler Mar 28 11:47
hmm
and the maxProcessors to?
Nick Collins @ndcollins Mar 28 11:48
maxProcessors is set to require('os').cpus().length - 1
donnyhardyanto @donnyhardyanto Mar 28 12:33
@evantahler, thank you. Yes it was tricky because we need to know the size before streaming. I am end up creating qr-code twice (first to string buffer - to get size, and second as readable stream) because I can’t figure out how to change string buffer to readable stream.
@evantahler, why we need to put error on the Action to next(error)? Is not gonna terminate the whole api right? Is there any treatment in the next() for the error like eroor logging or something?
donnyhardyanto @donnyhardyanto Mar 28 12:45
@evantahler, I got error when doing 'npm install —save’ after generating new project using latest Actionhero. NPM said No compatible version found: assert@^1.3.090.
Evan Tahler @evantahler Mar 28 12:49
@donnyhardyanto if you return an error to the action's callback, it will be rendrede to the client (and logged).
it doesn't terminate the server, no
just the connection
@donnyhardyanto as far as I see, assert is not required by actionhero or its dependants
actionhero@13.2.3 node_modules/actionhero
├── browser_fingerprint@0.0.6
├── is-running@2.0.0
├── async@1.5.2
├── mime@1.3.4
├── formidable@1.0.17
├── node-uuid@1.4.7
├── qs@6.1.0
├── node-resque@2.0.3
├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10)
├── ws@1.0.1 (options@0.0.6, ultron@1.0.2)
├── winston@2.2.0 (cycle@1.0.3, stack-trace@0.0.9, eyes@0.1.8, isstream@0.1.2, async@1.0.0, pkginfo@0.3.1, colors@1.0.3)
├── fakeredis@1.0.2 (redis@2.5.3)
├── uglify-js@2.6.2 (async@0.2.10, uglify-to-browserify@1.0.2, source-map@0.5.3, yargs@3.10.0)
├── ioredis@1.15.1 (flexbuffer@0.0.6, double-ended-queue@2.1.0-0, debug@2.2.0, bluebird@2.10.2, lodash@3.10.1)
├── primus@5.0.1 (demolish@1.0.2, emits@3.0.0, asyncemit@3.0.1, yeast@0.1.2, eventemitter3@1.1.1, forwarded-for@1.0.1, ultron@1.0.2, querystringify@0.0.3, load@1.0.2, setheader@0.0.4, create-server@1.0.1, url-parse@1.0.5, tick-tock@1.0.0, recovery@0.2.6, access-control@1.0.0, fusing@1.0.0, diagnostics@1.0.1)
└── i18n@0.8.1 (sprintf-js@1.0.3, mustache@2.2.1, debug@2.2.0, math-interval-parser@1.1.0, make-plural@3.0.3, messageformat@0.3.1)
and it installs just fine
donnyhardyanto @donnyhardyanto Mar 28 12:52
if developmentMode is false, will the error information will still rendered to client fully or only partial?
Evan Tahler @evantahler Mar 28 12:52
@donnyhardyanto yep
development mode is about exceptions, not errors
exceptions are true server crashes, like undefined variables
donnyhardyanto @donnyhardyanto Mar 28 12:52
So that mean ok if I delete the assert entry on package.json
Evan Tahler @evantahler Mar 28 12:53
or change the version I gues
Nick Collins @ndcollins Mar 28 19:16
@evantahler I think I figured it out. If I leave out the callback in the enqueue parameters when I call it from my test actuion, the task never executes. Also, using the actionhero enqueueTask CLI command it doesn’t execute either
Evan Tahler @evantahler Mar 28 22:41
@ndcollins that seems bad. Open a github issue with a test case please!
Nick Collins @ndcollins Mar 29 00:04
@evantahler in terms of production best practices, would you still recommend running actionhero behind nginx even if actionhero is functioning as an API-only server, and not serving any static content?
also, do you have any Heroku-specific best practices in terms of deployment strategies, clustering, etc.?
for example, on Heroku would you use start or startCluster?
donnyhardyanto @donnyhardyanto Mar 29 03:42
@evantahler, so if exception occur on action and developmentMode is true, then the api will terminate. What happen if developmentMode is false, is it still the worker will be terminated?
Evan Tahler @evantahler Mar 29 20:27
@donnyhardyanto developmentMode is only about reloading files on the fly. It has nothing to do with exceotion handling
if you crash, you crash :D
you can run cluster, and that will reload things and spawn a new process...
Evan Tahler @evantahler Mar 29 20:32
I normally recommend that even if you are running on a host/VM/dyno with only 1 CPU that you still launch your process with ./node_modules/.bin/actionhero startCluster. The reason for doing so is that if your process were to crash, the cluster module will restart it, and log the error which crashed the process. startCluster is also already aware of the hardware it is running on, and if it detects only 1 CPU, it will only fork off one child process.
However, Heroku has 2 features going for it which are the exception to the rule, and I actually advice making your start script ./node_modules/.bin/actionhero start (which can be written as simply actionhero start for shorthand in your package.json).
1) process.stdout logging is built in, and so any process crash will already be logged in the heroku logs
2) heroku will already detect a failure in your application (via a simple HTTP health check) and reboot your dyno if anything goes wrong. The above assumes that A) You are using a Dyno type which only has 1 CPU and 2) your app isn’t constantly crashing (Heroku will take ~1 minute or so to notice the failure and reboot your application. If your app is crashing a lot, or you find yourself with Dyno with more than 1 CPU, go back to using startCluster
So the simple scaling answer is: Run one actionhero process on the smallest Dyno you can, and scale horizontally. Finding “the smallest Dyno you can” then becomes only a mater of RAM. To get insist into this, you can either use a tool like NewRelic to monitor the running process(s) in production, or you can simply log out the heap usage for node every ~30s. Node is pretty good about garbage collection, and a normal “heavy” production app doesn’t normally go over 500MB, which fits in the “hobby” Dyno type.
In either situation (actionhero cluster or dyno scaling) you are only changing the number of running actionhero processes. It’s really only 1 axis… and the nuance comes from where you can fit them in. The Heroku router (details here) uses a random+round robin methodology for distributing requests, so be sure that all the Dynos in your cluster are of the same type (because the requests will be split evenly).
@ndcollins ^
donnyhardyanto @donnyhardyanto Mar 29 21:38
@evantahler so, if developmentMode is false, it will not reload it self when code changes?
if I run the cluster and has crash, the cluster will automatically spawn new worker, and log the error?
salles @sallespro Mar 29 21:46
@donnyhardyanto yes, yes.
Lea Anthony @leaanthony Mar 29 22:51
Does anyone know if it's possible to run some code on the master process only in a cluster setup? My experiments with using cluster.isMaster in an initializer have proven unsuccessful.
I'd like to start/stop an external service during starting and stopping of actionhero
Evan Tahler @evantahler Mar 30 00:36
@leaanthony not really. actionhero startCluster doesn't actually run most of the normal actionhero code... it won't run any initilziers or anything like that
it really just runs https://github.com/evantahler/actionhero/blob/master/bin/methods/startCluster.js
do you really need the master to do it, or do you just need to ensure that it happens once?
if you only need once, the task system and resque have a method to ensure that there is only one 'working' scheduler up and running... you can play off that
Evan Tahler @evantahler Mar 30 09:11
new release up!
https://github.com/evantahler/actionhero/releases/tag/v13.3.0
Strict Mode:
We now enforce javasctipt's strict mode (via 'use strict';) at the top of most Actionhero files. This enables easier opt-in to new ES6 features, and will help catch errors which might sneak by otherwise. You should notice no change in Actionhero's behavior. Newly generated files (Actions, Tasks, etc) will also contain the line 'use strict'; at the top of each file, but you can remove it if you don't want strict mode for some reason.
You can learn more about strict mode here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
by @ndcollins via evantahler/actionhero#799
by @evantahler via evantahler/actionhero#800
null HTTP Headers
You can now set some of the default HTTP headers to null if you don't want them returned to the client. For example, if you no longer want to send Access-Control-Allow-Origin, you can do the following in config/servers/web.js:
exports.production = {
servers: {
web: function(api){
return {
httpHeaders : {
'Access-Control-Allow-Origin' : null,
},
}
}
}
}
by @evantahler via evantahler/actionhero#803
Misc
Show which port/ip the web and socket server are bound to at boot
by @pauldevine via evantahler/actionhero#801
Update ESLint to latest version
Update docs to run/build documentation site on OSX
Thanks @ndcollins and @pauldevine for helping out!
Muhamed Krlić @l0oky Mar 30 09:24
Nice, new version. @evantahler figured out the sequelize plugin issue. I just needed to link the plugin to the project. Added a PR to prevent similar issues for everyone else :)
Evan Tahler @evantahler Mar 30 09:30
Ha, awesome.
Muhamed Krlić @l0oky Mar 30 09:30
Thanks ^^
Muhamed Krlić @l0oky Mar 30 10:39
@evantahler Sequelize plugin can now directly log through Winston :) l0oky/ah-sequelize-plugin@057625e
This message was deleted
Muhamed Krlić @l0oky Mar 30 11:06
Here's the updated version link. How do I add a new custom level? I tried api.config.logger.levels.mycustomlevel = 8 I get undefined var error
Evan Tahler @evantahler Mar 30 14:24
you need to set up the levels first before you use them (so it knows the order... is database above or below info?) for example.
that happens in config/logger in your project's top level
I would suggest using a level that already exists...
https://github.com/evantahler/actionhero/blob/master/config/logger.js#L42-L46
Lea Anthony @leaanthony Mar 30 15:53
@evantahler Thanks for the feedback. The real problem I’m trying to solve is sharing information (a cache) between the workers in a cluster. Ideally, fakeredis that works over tcp on localhost. I don’t want each worker to create this service, but to connect to it. Ideally this is something that can be started and stopped from within the server, rather than relying on it being available on startup. Thoughts?
donnyhardyanto @donnyhardyanto Mar 30 16:30
@leaanthony why dont you use redis? I learn that fakeredis cannot guaranteed work between worker process. Redis can work between process, and even between different machine.
Lea Anthony @leaanthony Mar 30 16:30
@donnyhardyanto Yeah, we can’t use redis unfortunately. Even if we did, it’d still be good to be able to start stop it in tandem with actionhero
donnyhardyanto @donnyhardyanto Mar 30 16:32
@leaanthony why you cannot use redis? It dont have to be start/stop tandem with action hero, we can leave running as service in memory, like mysql database
donnyhardyanto @donnyhardyanto Mar 30 16:50
@leaanthony if you cannot install redis on the machine, like because it not maintained by you, you can run redis-server as process, not as service
You can create script file to start your cluster, and in that script file you can start the redis-server before start the action hero cluster
and also create script file to stop your cluster, and in that file, after you send signal to kill the actionhero cluster, you can kill the redis-server
That way you dont have to install anything on the machine.
This message was deleted
donnyhardyanto @donnyhardyanto Mar 30 16:58
You can create VM using virtual box to match the machine os, and download the redis source and compile them
and you can move the binary file and and dependency to the machine
Muhamed Krlić @l0oky Mar 30 17:09
Has anyone run actionhero as a docker container before?
donnyhardyanto @donnyhardyanto Mar 30 17:11
@l0oky I dont have change to play with docker. It might alternative solution for @leaanthony problem thought. If I create the docker in Mac, can I run them in Linux?
Lea Anthony @leaanthony Mar 30 17:12
Thanks for the feedback. We simply cannot run redis at all
donnyhardyanto @donnyhardyanto Mar 30 17:13
@leaanthony why? Not enough memory?
or using Windows?
Lea Anthony @leaanthony Mar 30 17:13
policy
It’s an easy problem to solve. I just thought there might be a better way to start and stop processes on starting and stopping ah
donnyhardyanto @donnyhardyanto Mar 30 17:14
You can use script file
Muhamed Krlić @l0oky Mar 30 17:16
@donnyhardyanto thats the point of docker .. If its a container docker will run it what ever it is. and you can run docker crossplatform ( kind of, boot2docker )
donnyhardyanto @donnyhardyanto Mar 30 17:17
Cool
Muhamed Krlić @l0oky Mar 30 17:18
thats in theory i havent tried docker yet..
people say its that.. and frankly if it is that then its awesome
thats why i ask if anyone got actionhero to work with docker...
donnyhardyanto @donnyhardyanto Mar 30 17:28
The downside that it not free
?
Muhamed Krlić @l0oky Mar 30 17:28
yes it is
servers arent free ofc
https://github.com/docker/docker
@leaanthony there are other cool message queue projects like zeromq or rabbitmq
if redis is really forbidden
Lea Anthony @leaanthony Mar 30 17:46
I actually just want to pass data between workers. I’ll keep looking. Thanks.
donnyhardyanto @donnyhardyanto Mar 30 18:24
Use db or temp files
Evan Tahler @evantahler Mar 30 19:12
@leaanthony I know what you are up to. Look into the cluster.on message and process.send API. Node can communicate between parent and child in a cluster.
salles @sallespro Mar 30 21:02
@leaanthony redis would be perfect, maybe etcd complies with the policy you mentioned. https://github.com/coreos/etcd
@l0oky i have used AH with docker, i think it offers a lot of very good features for distributed, microservices based apps.
Evan Tahler @evantahler Mar 30 21:56
To clarify @leaanthony's predicament, he's in an environment where he can't install ANY extra processes. Any new database, consensus tool, etc is a non-starter.
Whatever needs to be done, needs to be done within the actionhero node process itself.
Muhamed Krlić @l0oky Mar 31 04:12
@sallespro Was It hard to set up? You have to foward the ports from container to the outside world?
Eugene Dementev @rizr Mar 31 08:21
Hello, where in AH I can store my service-modules like locationService or Payment ? In initializers? already in initializers AH stores middlewares, and that bad idea mix logiic of middlewares , services, and etc in one folder
Evan Tahler @evantahler Mar 31 09:05
If you are just talking about project organization, subfolders?
Eugene Dementev @rizr Mar 31 09:15
@evantahler yes
Muhamed Krlić @l0oky Mar 31 09:17
@rizr well you build your own logic if that makes sense
its all about being lightweight
and being close to the inner guts of the framework
all middlewares do is edit the api object and add "middleware" function for use in action
Eugene Dementev @rizr Mar 31 09:21
you mean if I'm create sub-folder Services, and PaymentService.js in him, I can edit Api object?
Muhamed Krlić @l0oky Mar 31 09:21
You dont get this much freedom in other frameworks, like loopback IBM thing
you can do that, just make an initializer that correctly manages your logic
Eugene Dementev @rizr Mar 31 09:22
bad( I am 2yers coding on Sails.js, and we have Services folder
Muhamed Krlić @l0oky Mar 31 09:26
haha ok
Terminal command mkdir Services is the same in all unix os systems :smile:
Eugene Dementev @rizr Mar 31 09:30
I mean the Service folder and all files exposed to framework. http://sailsjs.org/documentation/concepts/services/creating-a-service
Muhamed Krlić @l0oky Mar 31 09:34
You didn't mean much, obviously. When you seek help from somebody expose as many details you can.. otherwise I am sorry.
Maybe start with what your needs are?
Muhamed Krlić @l0oky Mar 31 09:52
@rizr The practice is we make an initializer a plugin that will work what Its supposed to for any AH project If Its used many times. Which makes easy addition of new features in other AH projects. A good example of this is ah-sequelize-plugin, you simply include it into your AH project and you have sequelize orm at your disposal, It exstends the global api object to fit your application needs. And thats what you do If you want to 'organize' your project files. I hope that clears things up a bit
The good news is any initializer you make for your project lets say a email sender. All you have to do is essentially copy and paste It into a plugin package
Muhamed Krlić @l0oky Mar 31 09:59
and from there you can share it as a npm package or just build it for your project
Muhamed Krlić @l0oky Mar 31 10:06
overall imo project structure of actionhero is really solid and when you get the idea it really is one of the best if not the best structures for building any kind of api.
kudos to @evantahler for that :)
The real actionhero issues are small active community and is the technology that it uses outdated.
Muhamed Krlić @l0oky Mar 31 10:14
In any case I am planning to write a book about this framework when I grasp the inner workings of it. So any questions you ask on gitter will help me write it :smile: , especially these kind of questions @rizr about the idea of actionhero itself.
Evan Tahler @evantahler Mar 31 10:35
@l0oky @rizr here's a real example of making a similar "service" in actionhero
https://gist.github.com/evantahler/a55a2e6b192134faaa90c29157721388
then in your actions or wherever, just call api.email.send(to, subject, body)
examples are usually more helpful than not, @l0oky :D
and write that book before node summit (june) and I'll bet you can get a free ticket!
Muhamed Krlić @l0oky Mar 31 11:51
@evantahler Yeah, note to self: make a lot of examples in the book. Dont get excited too fast haha I planned it to take a few years to write :D yeah lets face it I am not a good writer :)
Eugene Dementev @rizr Apr 01 04:21
You are planing migrate to es2015 ?
Krishna Glick @krishnaglick Apr 01 11:38
@evantahler I was going to make changes to a few other places... lol
Zhonghai Zuo @zhhz Apr 01 11:46
websocket
Muhamed Krlić @l0oky Apr 01 11:46
? :)
Zhonghai Zuo @zhhz Apr 01 11:46
Sorry, typo :(
Muhamed Krlić @l0oky Apr 01 11:46
haha no worries
Zhonghai Zuo @zhhz Apr 01 11:48
here is my question, is it possible for me to use io-client to communicate with AH server, like: var io = require('socket.io-client');
var socket = io('http://localhost:8080')
socket.on('connect', function(socket){
console.log('Connected!!!!');
})
Krishna Glick @krishnaglick Apr 01 11:48
You should be able to fine, assuming you have an endpoint for it.
Zhonghai Zuo @zhhz Apr 01 11:49
currently I'm getting: 2016-04-01 14:48:52 - debug: [ file @ web ] to=127.0.0.1, file={404: not found}, size=null, duration=null, success=false
Muhamed Krlić @l0oky Apr 01 11:50
Does It connect?
Zhonghai Zuo @zhhz Apr 01 11:50
nope :(
above is the console log from AH
Krishna Glick @krishnaglick Apr 01 11:51
I'm not sure but you may need to configure a route for it.
Zhonghai Zuo @zhhz Apr 01 11:52
@krishnaglick can you give me more info, I'm new to AH. :smile:
Krishna Glick @krishnaglick Apr 01 11:53
/config/routes.js
all: [ path: '/', action: 'myWebsocketActionName' ]
Zhonghai Zuo @zhhz Apr 01 11:54
I see, thank you @krishnaglick
Krishna Glick @krishnaglick Apr 01 11:55
That MAY work. I haven't worked with websockets myself, but it's a thought. :)
Zhonghai Zuo @zhhz Apr 01 11:55
haha, same here, but I'll try it first...
Krishna Glick @krishnaglick Apr 01 11:55
:D
Zhonghai Zuo @zhhz Apr 01 12:01
@krishnaglick I must did something wrong, not working, the AH has the same log: 2016-04-01 14:58:16 - debug: [ file @ web ] to=127.0.0.1, file={404: not found}, size=null, duration=null, success=false
Krishna Glick @krishnaglick Apr 01 12:01
https://en.wikipedia.org/wiki/HTTP_404
It can't find it
Zhonghai Zuo @zhhz Apr 01 12:01
socket.on('connect', function(socket){
console.log('Connected!!!!');
}) the client log was not executed...
Krishna Glick @krishnaglick Apr 01 12:02
https://github.com/evantahler/actionhero-tutorial/#websockets
Take a look through that
Zhonghai Zuo @zhhz Apr 01 12:04
Yes, I did.
Muhamed Krlić @l0oky Apr 01 12:09
@zhhz Did you enable websockets server? config/servers/websocket.js
enabled: true
Zhonghai Zuo @zhhz Apr 01 12:13
@l0oky yep, it's enabled.
Muhamed Krlić @l0oky Apr 01 12:16
Probably something with socket.io-client
Zhonghai Zuo @zhhz Apr 01 12:16
even the http://localhost:8080/websocketLoadTest.html runs perfectly, but the socket.io-client still not working
haha, you beat me...
Muhamed Krlić @l0oky Apr 01 12:17
websocketLoadTest.html has its own client actionheroClient
Zhonghai Zuo @zhhz Apr 01 12:17
yep, you are right. I'm using 1.4.5 socketio
Muhamed Krlić @l0oky Apr 01 12:18
public/javascript/actionheroClient.js
try that client
It uses custom Primus websocket client.
Zhonghai Zuo @zhhz Apr 01 12:19
I thought about it, but how do I specify the server ip/host name?
Muhamed Krlić @l0oky Apr 01 12:19
http://www.actionherojs.com/docs/#general103
That's already taken care of for you.
actionheroClient.js is generated after you run actionhero instance
Refer to the config/servers/websocket.js file to see where your file is generated. Usually public/javascript/actionheroClient.js
Zhonghai Zuo @zhhz Apr 01 12:22
working on it...
Muhamed Krlić @l0oky Apr 01 12:23
You can also take a look at Primus for documentation on methods you may want to try
actionheroClient is based on Primus
Zhonghai Zuo @zhhz Apr 01 12:26
Yep, seems like I can pass in an options object, which I can config the url...
new ActionheroClient(options, client), am I on the right track?
Synth Meat @synthmeat Apr 01 12:37
wait. didn't actionhero have grunt tasks?
Krishna Glick @krishnaglick Apr 01 12:37
Grunt was removed iirc
Muhamed Krlić @l0oky Apr 01 12:38
@zhhz Just do client = new ActionheroClient();
There's example code in actionhero docs
Zhonghai Zuo @zhhz Apr 01 12:39
but I want it be node app, meaning I can run like node the_io_client.js
I'm not pulling the ahclient js from the server...
Synth Meat @synthmeat Apr 01 12:41
@zhhz, then you want this https://github.com/evantahler/actionhero-client
not actionhero frontend client bundled with actionhero
i'd dig that clients were totally separated from backend bit myself. so, actionhero-browser-client, actionhero-node-client, actionhero-unity-client, ...
Zhonghai Zuo @zhhz Apr 01 12:42
wow... that's exactly I'm looking for, thanks man
Thanks everyone for the help, much appreciate it!!!
Muhamed Krlić @l0oky Apr 01 12:44
:+1:
Evan Tahler @evantahler Apr 01 22:49
@zhhz let me know how using that module goes. It's been a while since I updated it.
Evan Tahler @evantahler Apr 01 23:04
but... it still seems to be working fine! Huzzah for a consistent client-facing API!
Nebukadneza @Nebukadneza Apr 02 11:36
hi there
Muhamed Krlić @l0oky Apr 02 11:36
Hello :)
Nebukadneza @Nebukadneza Apr 02 11:37
i’ve been looking for nice API endpoint frameworks for node, and stumbled across AH, which looks quite nice (the typos in the docs aside :D)
Muhamed Krlić @l0oky Apr 02 11:37
Hahaha
Nebukadneza @Nebukadneza Apr 02 11:37
however, i was wondering … it’s not paticularly suited for the RESTful API style, right?
Muhamed Krlić @l0oky Apr 02 11:37
Ask away! :D
It can be
Nebukadneza @Nebukadneza Apr 02 11:39
hm, ok - but then, don’t i need to set tons of exports.routes?
possibly multiple per action?
Muhamed Krlić @l0oky Apr 02 11:39
In the newer versions there were changes on this issue. Well now you can make RESTful APIs
Nebukadneza @Nebukadneza Apr 02 11:39
is there maybe an example of how to do it?
Muhamed Krlić @l0oky Apr 02 11:40
Never did RESTful with AH myself. I am interested in the example too. Maybe @evantahler can help :)
Nebukadneza @Nebukadneza Apr 02 11:44
evantahler/actionhero#29
this is the closest to a clearification i could find
however from everything i’ve read is that AH is not well suited for restful APIs :/
Evan Tahler @evantahler Apr 02 12:24
not at all!
just... make a routes file:
here's an example
Muhamed Krlić @l0oky Apr 02 12:25
@evantahler to the rescue! :D
Evan Tahler @evantahler Apr 02 12:26
https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf/blob/master/config/routes.js
it's a pretty easy mapping
and you can do some auto variable mapping: http://www.actionherojs.com/docs/#routes
Evan Tahler @evantahler Apr 02 12:39
I'm curious @Nebukadneza, where did you see that actionhero was bad at REST?
also... please point out any typos so we can fix them :D
Muhamed Krlić @l0oky Apr 02 13:31
https://www.youtube.com/watch?v=2f-BcKEfUKM
Wow
Krishna Glick @krishnaglick Apr 02 14:24
Does AH clustering auto-load balance? I'm mulling over an idea in my head for an AH backend utilizing websockets and was thinking I could track the number of connections, and if needed, spin up a new instance. But I don't know if incoming requests will go where they need to go.
Krishna Glick @krishnaglick Apr 02 17:02
Based on the documentation I'd need something like nginx or the like.
Muhamed Krlić @l0oky Apr 03 07:19
Did anyone use git squash? https://github.com/blog/2141-squash-your-commits
Is it any good?
Evan Tahler @evantahler Apr 03 08:44
@l0oky that's a personal prefrece. Do you want real history in git or sanitized history? It has more to do with your code review style than anything
@krishnaglick you should always use something like ngobx
nginx
It's better than node for serving assets, ssl termination, etc.
But node cluster module will round robin connections to the sub processes.
Krishna Glick @krishnaglick Apr 03 11:08
What made you chose Primus over something like Sockets IO?
Evan Tahler @evantahler Apr 03 12:43
we used to use socket.io. it doesn't scale well past 1 server, it doesn't have a shared bus, and (at the time) it was pretty buggy
so then we moved to faye
which worked pretty great, but its redis message bus was more or less a similar implementation of the one we had
and we needed to enable it for more than just WS (ie: a WS client should be able to talk to a SOCKET client)
Then we found primus, which lets you use whatever you want under the hood (engine.io (which is the guts of socket.io), faye, etc). It's the best of all worlds
so if you want to be "socket.io compatibile" use the engine.io transport inside of primus and you should be good-to-go
Krishna Glick @krishnaglick Apr 03 15:52
I'm poking around w/ web sockets and wanted something fairly lightweight. I know ActionHero's pretty clean and the auto-clustering seemed really cool.
Evan Tahler @evantahler Apr 03 16:31
The main issue with stateful connections is handling the server discovery. If you reconnect (or you fall back to long polling) how can you be sure you hit the same server... Or fully revuild the connection object without too much overhead.
Krishna Glick @krishnaglick Apr 03 16:32
Out of the box does AH + Primus handle all that, assuming I use ActionHero Client?
Evan Tahler @evantahler Apr 03 16:32
That's a problem with in server + many processes (under node cluster) or many servers. Sticky connections on your load balacer aren't enough sadly
Yep. That's the whole "doCluster" thing, which relies on redis to syndicate state
Krishna Glick @krishnaglick Apr 03 16:33
Cool. I'm gonna swap over to AH + AH Client instead of Sockets for this. :D
Evan Tahler @evantahler Apr 03 16:33
It's not "lightweight" in that it relies on redis,and has a lot of code, but it should be "simple to use" in that it should work :)
Krishna Glick @krishnaglick Apr 03 16:34
While I'd love to optimize for speed and whatever from the beginning, if this project ever gets to the point where performance >>> ease of use I'll put the time in then.
And I imagine having proper clustering would allow for better scaling anyway.
Evan Tahler @evantahler Apr 03 17:46
That's how I feel :)
Good luck!
Krishna Glick @krishnaglick Apr 03 17:46
Thanks!
Krishna Glick @krishnaglick Apr 03 19:09
Browserify doens't like actionhero-client
Evan Tahler @evantahler Apr 03 23:00
Why would you browserify it? It's alrwady minified and generated in your public dir
Krishna Glick @krishnaglick Apr 04 06:04
For require() syntax. 2. Single bundle.js file. 3. I tried installed actionhero-client however it still ran into issues w/ browserify and require.
Evan Tahler @evantahler Apr 04 07:14
Oh. Actionhero client is for sever-server, and uses the "socket" server
We socket server generates the client JS automatically into the "public" folder.
Krishna Glick @krishnaglick Apr 04 07:16
Ah, explains why it didn't work. I'll just bring in both scripts then.
Chad Robinson @crrobinson14 Apr 04 18:30
Anybody here doing any TypeScript with ActionHero?
Evan Tahler @evantahler Apr 04 19:20
Not I
Krishna Glick @krishnaglick Apr 05 09:53
Where's the repo for the docs? I found a typo: "callback will contain (error, detauils)"
Chad Robinson @crrobinson14 Apr 05 14:50
@evantahler I'm still having one remaining issue with stuck tasks. Specifically during a deployment, do you have a best practice for what to do with restarting a node that has a running task? If I do a deployment on a node that is in the middle of a job, that job gets stuck. I have an entry in resque:delayed:RUNTIME for it and it never gets cleaned up / restarted. My deployment stops the process with SIGTERM, FWIW.
I can't do a hot-reload with USR2 because this particular deployment includes a database migration. It's not safe.
The only way I've been able to recover these is a FLUSHDB or a manual deletion of the job lock and other records, which is tedious and error-prone.
Evan Tahler @evantahler Apr 05 14:56
@krishnaglick just the "site" folder in the main repo. Fix it for me please!
@crrobinson14 that sucks. SIGTERM should still allow a graceful shutdown
https://github.com/evantahler/actionhero/blob/master/bin/methods/start.js#L110-L111
there is a 30s window to "shut down gracefully" https://github.com/evantahler/actionhero/blob/master/bin/methods/start.js#L12
are your jobs slower than 30s?
(and you can configure this)
Chad Robinson @crrobinson14 Apr 05 15:12
It's hard to say, they're Algolia indexing/expiration jobs and I sometimes have flaky responses to them. I've changed my settings so they run more often but against fewer records per batch - we'll see if that helps.
Evan Tahler @evantahler Apr 05 15:14
K.
Keep js posted!
What's Algolia?
Krishna Glick @krishnaglick Apr 05 16:36
Handled.
Evan Tahler @evantahler Apr 05 18:30
:)
Krishna Glick @krishnaglick Apr 05 19:38
I'm attempting to communicate with my server over websockets. I have an action named 'joinServer', and I client.connect() followed by client.action('joinServer', {my: 'object'}, console.log);
I get stuff added to data.response, however data.params is not populated with {my: 'object'}. Is there something crucial I'm missing? :s
Evan Tahler @evantahler Apr 05 22:16
Well, "my" in your example would need to be a param listed in your actions definition.
Arbitrary params are filtered out by default
Same as when accessing actions over HTTP
Krishna Glick @krishnaglick Apr 06 06:30
Oh... I was scouring the WebSocket documentation portion when what I really needed was to read up on actions. >>' ty
Krishna Glick @krishnaglick Apr 07 16:49
How can I intercept new websocket connection requests? The server spits out '[server: websocket] new connection to=IP' but I want to hook into that as well.
Evan Tahler @evantahler Apr 07 18:51
Connection middleware
Krishna Glick @krishnaglick Apr 07 19:50
Didn't seem to catch it, but I realized I didn't need to get the fingerprint until a later action was called so it worked out. :)
Matt @mattrepublic Apr 08 14:41
I feel like I'm missing something obvious here, but if someone wouldn't mind clarifying this for me I would really appreciate it!
I'm trying to run two clusters on a Heroku server (and locally). When I run actionhero startCluster I locally get the message: notice: cluster equilibrium state reached with 2 workers. On Heroku I get the message: notice: pid: 17 and uncaughtException: 32ee7021d23f4e478673b36187f2446a.
What am I overlooking?
Evan Tahler @evantahler Apr 08 15:50
well... it's crashing for some reason. try running just one server (actionhero start) and see if that provides anything more useful. Otherwise, you'll need to figure out how to read all the other logs the servers make
Matt @mattrepublic Apr 09 05:50
Thank you. I'll certainly dig into it more. I was worried I was missing something when I was running it.
n-s-k @n-s-k Apr 09 06:27
I have a very newbie question, is there a step by step guide to upgrade AH 12.x.x => 13.x.x? I know right...
Evan Tahler @evantahler Apr 09 08:58
@n-s-k nothing official. Change your package.json. You probably want to copy fresh config files in from a new action hero project.
n-s-k @n-s-k Apr 09 08:59
@evantahler that's what I've done, I feel less stupid now thanks.
Krishna Glick @krishnaglick Apr 09 17:27
Am I doing something wrong or is this the right way to add intercepts to websocket connect/disconnect?
let wsServer = api.servers.servers.websocket.server;
wsServer.on('', () => {});
I've tried using api.connections.addMiddleware(middleware); but it doesn't catch connect/disconnect.
Evan Tahler @evantahler Apr 09 17:40
Nope. The way you say didn't work... Works.
What's your middleware look like?
And actually action hero's connections are actually a little abstracted from the WS connection events.
You don't want to listen to those, they'll be really spammy and noisy.
Krishna Glick @krishnaglick Apr 10 17:45
Ah, see I was using the preProcessor event thinking it was the same across the board. I needed to hook into create/destroy. My bad. Keep thinking I've read deep enough into the docs only to find more things. ^^
Evan Tahler @evantahler Apr 10 21:22
@krishnaglick there are 3 types of middleware: action, connection, and chat, each operating on seperate lifecycle events
Evan Tahler @evantahler Apr 10 21:29
@krishnaglick for you, I added this to the readme: evantahler/actionhero@d67fb57
Krishna Glick @krishnaglick Apr 11 05:58
Haha, thanks! :D
luisgtz @luisgtz Apr 11 07:07
hi all, I am just starting to use actionhero, following the tutorials but wonder if it is possible to start actionhero on other port than port 8080, I set env variable PORT with value 80 but it failed
Krishna Glick @krishnaglick Apr 11 07:07
config > servers > web.js > port: process.env.PORT || 8080
luisgtz @luisgtz Apr 11 07:08
yep, that is the one that I changed but it failed, let me post the error
emerg: Error with initializer step: start
2016-04-11T14:09:11.334Z - emerg: Error: cannot start web server @ 0.0.0.0:80 => listen EACCES
at Server.<anonymous> (/home/luisgtz/remove/actionh_test/node_modules/actionhero/servers/web.js:62:21)
npm ERR! Failed at the my_actionhero_project@0.0.1 start script 'actionhero start'.
npm ERR! This is most likely a problem with the my_actionhero_project package,
npm ERR! not with npm itself.
Krishna Glick @krishnaglick Apr 11 07:10
What's at line 62 in your web.js file?
luisgtz @luisgtz Apr 11 07:11
a comment
Krishna Glick @krishnaglick Apr 11 07:11
Okay, can you paste your web.js file here? http://hastebin.com/
I'll take a peek.
luisgtz @luisgtz Apr 11 07:17
I pasted and clicked save
Krishna Glick @krishnaglick Apr 11 07:18
Send me the rul
url*
Evan Tahler @evantahler Apr 11 07:21
@luisgtz port 80 (all ports under 100) are protected by the system. You need to be root/sudo to start a process on that port
Your error "eaccess" means the node process doesn't have the permission it needs to use that port
luisgtz @luisgtz Apr 11 07:23
ok, let me try as root
you were right, that solve my problem
thanks to both of you @krishnaglick @evantahler
Krishna Glick @krishnaglick Apr 11 07:24
np, glad you got it working
Evan Tahler @evantahler Apr 11 08:13
new release!
https://github.com/evantahler/actionhero/releases/tag/v13.3.2
Localized goodbyeMessage for socket clients
You can now configure the message the server sends to connections on the socket server type with api.config.servers.socket.goodbyeMessage. This string can be localized.
by @evantahler via evantahler/actionhero#817
Documentation updates.
Thanks to @krishnaglick, @iSimar, @peterlandry, and @evantahler for their work keeping out documentation up to date!
Misc
Updated ioredis to the latest version
Krishna Glick @krishnaglick Apr 11 10:01
Is there a way to get console.log output during cluster mode?
Greg Coonrod @gcoonrod Apr 11 10:12
@evantahler: Is there an intentional reason that the action processor does not wrap actionTemplate.run() in a try catch block?
Evan Tahler @evantahler Apr 11 10:19
@krishnaglick nope... because stdout is not nesicarily bound to any terminal window, especially when you fork. Use api.log, so it will go to a file
@gcoonrod because it is very likley to be async?
we used to wrap that in a domain/catch, but that's a bad idea now
some more details here => evantahler/actionhero#737
Greg Coonrod @gcoonrod Apr 11 10:20
Would wrapping it in a try catch now introduce unwanted behavior?
I know that it will only catch synchronous errors
donnyhardyanto @donnyhardyanto Apr 11 10:27
Hi @evantahler, I was putting my actionhero api on production. I am using startCluster, and only have 1 task, and it is a periodic task (it was the one I show you before). The periodic task is running per 2 seconds, and in task queue config I set to check task queue per 1 seconds. The periodic task has a lot reading to db, and it is async (I call processNextTick in the loop while waiting result in db). The api stack is running smoothly for 5 days, and suddenly cannot process some of the actions, and they as the actions that waiting for the result from the periodic task. And when I stop the cluster and restart again, the periodic task is not running. Only after I delete the resque branch key in Redis, and restart the cluster again, the periodic task is running again. And sometime it only running for 1 day before it has same trouble, and sometime may be 4 days before it has same trouble.
So far when I look at the cluster log, and action hero log and also the redis log, I cannot find anything (error or warning what so ever).
I figure it was somehow the queue got locked?
Evan Tahler @evantahler Apr 11 11:29
@gcoonrod I don't really think so... the vast majority of actions are async, and to that end, adding a try/catch would likley confuse some folks about the depth/level of error handling the framework provides
I could see adding a try/catch at boot to alert about parsing errors, but that's all I can really think of
@donnyhardyanto yep, it looks like your worker is getting 'stuck'. The only really thing you can do is add a TON of logging to see where in your jobs the job is getting stuck
Greg Coonrod @gcoonrod Apr 11 11:30
@evantahler: what about something like https://github.com/evantahler/actionhero/compare/v12.5.0...gcoonrod:actionTimeout
Evan Tahler @evantahler Apr 11 11:30
it looks like the job was "working" when you restarted, so when the server came back it didn't try to re-enqueue that periodic job
@gcoonrod 1) you can do that in a middleware now
Greg Coonrod @gcoonrod Apr 11 11:31
The issue my team is running into is either uncaught errors or unresolved promises prevent next() from being called in actions.
Evan Tahler @evantahler Apr 11 11:31
and 2) absoulty not! that's very unsafe!
the reason it is unsafe is that you are ending the connection but not whatever the connection was working on
so you sill probably have a DB operation chugging along and then when its done, it will crash your server because the rest of the action can't process
and you can't stop that DB action, roll back, etc like you would really want to
these are the problems of asyn code :(
here's my suggestions
Greg Coonrod @gcoonrod Apr 11 11:33
yeah, i'm aware of that. we're groping in the dark a bit right now. We keep running into hung actions and hung tasks in our production environments.
the more async code we add the more of these types of issues we run into.
Evan Tahler @evantahler Apr 11 11:33
I would suggest you re-implament the domain stuff even though it's not "recommended"
in a middleware
then, if there's ever an uncaught/unresolved error in the domain, you can catch it, AND your code will be able to rollback (assuming you hook into the middleware properly)
do you use a tool like bugsnag?
a runtime error reporter?
that's really what you need here
letting the actionhero process crash is actually the safest thing to do (assuming you can reboot quickly)... you just need to get the stack trace out to a log or 3d-party service so you can see what's going wrong
Greg Coonrod @gcoonrod Apr 11 11:37
we haven't tried any runtime error reporters.
Evan Tahler @evantahler Apr 11 11:37
they are worth their weight in gold :D
Greg Coonrod @gcoonrod Apr 11 11:37
will they catch the errors that promises swallow?
Evan Tahler @evantahler Apr 11 11:38
well.. it depends on how your code is written...
if there's an uncaughtException, yes
if there's an unhandledRejection, yes
anything else... you are already probably suppressing/handling
but you can pass errors to the reporter as needed
Greg Coonrod @gcoonrod Apr 11 11:39
and that is the root of the problem I think we silently swallow lots of errors.
Evan Tahler @evantahler Apr 11 11:39
don't do that :D Become zen with the knowledge that you will crash :D
it's a natrual part of life
you can always reboot
(coming from Ruby, this was one of the hardest things to get used to in node)
for me
question for you though:
here's an action that uses promises and callbacks to interface with the database
https://github.com/evantahler/actionhero-angular-bootstrap-cors-csrf/blob/master/actions/user.js#L1-L30
(create user)
all possible errors are handled here, both callback errors and catch errors... what are you doing to suppress errors more globally?
(api.models.user is a sequelize object) => sequelizejs.com
Greg Coonrod @gcoonrod Apr 11 11:43
what if api.models.user.build(data.params); throws an error?
Evan Tahler @evantahler Apr 11 11:44
so taht could be in a try/catch, because its gaurnteeed to be a sync operation
or, because I would use input validations, I know the state of the data coming in, so it woud (almost) never thow
Greg Coonrod @gcoonrod Apr 11 11:44
so technically that is a potentially uncaught exception?
Evan Tahler @evantahler Apr 11 11:45
sure, and then the server would crash, I would get a log about it, and the server would reboot
in that case, I would also get an email from bugsnag with the new crash, and I would fix it
Greg Coonrod @gcoonrod Apr 11 11:45
where do you get the log?
Evan Tahler @evantahler Apr 11 11:45
wherever api.log is logging too?
Greg Coonrod @gcoonrod Apr 11 11:46
but what caught the unhandled exception?
Evan Tahler @evantahler Apr 11 11:46
perhaps I look at the file | grep "error", perahps my logs are going to someplace like splunk... depends on your deployment topology more than anything
oh, bugsnags implamentation is something like process.on('uncaughtError', sendEmail)
it's fancier than that, but that's a good mental model for it
Greg Coonrod @gcoonrod Apr 11 11:47
ah
Evan Tahler @evantahler Apr 11 11:47
we do similar things in actionhero when runnign in cluster mode
https://github.com/evantahler/actionhero/blob/master/bin/methods/start.js#L90-L108
so if the child worker dies, the cluster master will log out why
Greg Coonrod @gcoonrod Apr 11 11:48
ah, the cluster master log, my old nemesis
we don't currently exfil the cluster master log to our 3rd party logging tool in production.
which is a problem
Evan Tahler @evantahler Apr 11 11:48
:D
You can do a fun test locally
just make an action which refrences an un-defined variable or something like that
Greg Coonrod @gcoonrod Apr 11 11:49
so, that is actually exactly the bug we ran into today
but we're on 12.5.0
so that blob you sent me isn't in our code base
Evan Tahler @evantahler Apr 11 11:50
I think that stuff was added in v13 too
so if this is my action
Greg Coonrod @gcoonrod Apr 11 11:50
:(
Evan Tahler @evantahler Apr 11 11:50
exports.action = {
name: 'bad',
description: 'bad',
blockedConnectionTypes: [],
outputExample: {},
matchExtensionMimeType: false,
version: 1.0,
toDocument: true,
middleware: [],
inputs: {},
run: function(api, data, next) {
yay; // <- here
next();
}
};
here's what happens now
> ./bin/actionhero startCluster --workers 1
2016-04-11T18:51:32.891Z - info: actionhero >> startCluster
2016-04-11T18:51:32.904Z - notice: - STARTING CLUSTER -
2016-04-11T18:51:32.905Z - notice: pid: 43315
2016-04-11T18:51:32.911Z - info: starting worker #1
2016-04-11T18:51:33.097Z - info: [worker #1 (43316)]: starting
2016-04-11T18:51:33.984Z - info: [worker #1 (43316)]: started
2016-04-11T18:51:33.985Z - notice: cluster equilibrium state reached with 1 workers
2016-04-11T18:51:44.775Z - alert: [worker #1 (43316)]: uncaught exception => yay is not defined
2016-04-11T18:51:44.775Z - alert: [worker #1 (43316)]: ReferenceError: yay is not defined
2016-04-11T18:51:44.775Z - alert: [worker #1 (43316)]: at Object.exports.action.run (/Users/evantahler/Dropbox/Projects/actionhero/actions/bad.js:14:5)
2016-04-11T18:51:44.775Z - alert: [worker #1 (43316)]: at /Users/evantahler/Dropbox/Projects/actionhero/initializers/actionProcessor.js:268:31
2016-04-11T18:51:44.775Z - alert: [worker #1 (43316)]: at /Users/evantahler/Dropbox/Projects/actionhero/initializers/actionProcessor.js:149:9
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at /Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:726:13
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at /Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:52:16
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at iterate (/Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:260:24)
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at async.forEachOfSeries.async.eachOfSeries (/Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:281:9)
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at _parallel (/Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:717:9)
2016-04-11T18:51:44.776Z - alert: [worker #1 (43316)]: at Object.async.series (/Users/evantahler/Dropbox/Projects/actionhero/node_modules/async/lib/async.js:739:9)
2016-04-11T18:51:44.777Z - alert: [worker #1 (43316)]: at api.actionProcessor.preProcessAction (/Users/evantahler/Dropbox/Projects/actionhero/initializers/actionProcessor.js:148:13)
2016-04-11T18:51:44.777Z - notice: cluster equilibrium state reached with 1 workers
2016-04-11T18:51:44.785Z - info: [worker #1 (43316)]: exited
2016-04-11T18:51:44.785Z - info: starting worker #1
2016-04-11T18:51:44.960Z - info: [worker #1 (43323)]: starting
2016-04-11T18:51:45.827Z - info: [worker #1 (43323)]: started
2016-04-11T18:51:45.827Z - notice: cluster equilibrium state reached with 1 workers
nice stack trace and a reboot
you don't need to use startCluster obviously, this is just an example of the "node-y" way of doing things
base actionhero boots up in under 1s... so that's nice
Greg Coonrod @gcoonrod Apr 11 11:53
we are running AH in a cluster
Evan Tahler @evantahler Apr 11 11:54
sure, and I ususally suggest folks do, but there's more to that as well
for example, In "production", you should always have something upstream, like NGINX that can handle the 500 response
in my example, the client who hit the broxen API is actually never sent back any data
so nginx (or a load balancer) would need to know the connection was terminated pre-maturely and send some error page to the client
Greg Coonrod @gcoonrod Apr 11 11:55
which is what we're seeing as well, so the waiting client hits its internal timeout and closes the connection
Evan Tahler @evantahler Apr 11 11:55
cool
so yeah... the general path forward I would suggest:
1) let the app crash, don't be defensvie
2) get some good logging in place, which may include a 3d party crash aggregator like bugsnag
3) drill down to the problems and fix them 1-by-1 rather than globally suppressing
4) upgrade to actionhero v13
Greg Coonrod @gcoonrod Apr 11 11:57
those are all good suggestions, thanks Evan!
Evan Tahler @evantahler Apr 11 11:58
happy to help!
Greg Coonrod @gcoonrod Apr 11 11:58
So I shouldn't submit the timeout PR?
Evan Tahler @evantahler Apr 11 11:58
hah, no
Greg Coonrod @gcoonrod Apr 11 11:58
lol
Evan Tahler @evantahler Apr 11 11:58
if you learn anything useful, or come up with some tips, PLEASE add them here http://www.actionherojs.com/docs/#production-notes
I'll add something about "crashing"
Evan Tahler @evantahler Apr 11 12:08
@gcoonrod => evantahler/actionhero@c00a600
Greg Coonrod @gcoonrod Apr 11 12:10
Looks great.
donnyhardyanto @donnyhardyanto Apr 11 14:30
@evantahler, if schedule for periodic task per 2 seconds, and task checking for queue is every 1 sec. If task finish within 1 sec it should be no problem with locking right? But what happen if the task somehow finish in 10 secs, is there any possibility the lock is not release?
Evan Tahler @evantahler Apr 11 15:31
if the task crashes, the lock will not be released, almost always
but otherwise, speed shouldn't be a problem, no
donnyhardyanto @donnyhardyanto Apr 11 15:37
So, if I wrap it up in try/catch, and ignore the exception, it should be no crashing right?
Evan Tahler @evantahler Apr 11 16:42
well... you should figure out why it is crashing and stop it :D
also, it's pretty likley whatever is causing the problem is not a sync actviity (talking to a database or something) and try/catch won't help
this is releated to the converstaion @gcoonrod and I just had ^
donnyhardyanto @donnyhardyanto Apr 11 18:14
I cannot not use startCluster, because it will terminate because the libuv
(may be that the cause).
Chad Robinson @crrobinson14 Apr 11 18:16
Is anybody else here getting 'undefined' messages in their logs due possibly to a recent change in i18n?
donnyhardyanto @donnyhardyanto Apr 11 18:16
starting actionhero without cluster always (never not) end up crashing because assert n==0 in libuv
it is version v13
correction: because assertion n==sizeof(val) failed libuv/libuv#401
so I use startCluster to automatically restart the process when encounter this bug
It always like that in Linux. On Windows I never had this problem.
donnyhardyanto @donnyhardyanto Apr 11 18:22
Because libuv is for linux threading?
Evan Tahler @evantahler Apr 11 21:26
@donnyhardyanto I don't really know what you are talking about
can you not start actionhero? can you not stat actionhero startCluster?
@crrobinson14 what type of log? Action? Task?
donnyhardyanto @donnyhardyanto Apr 11 21:46
When I am using actionhero start, the actionhero will crash after couple hours, because assertion n==sizeof(val) failed libuv/libuv#401
So I when I use actionhero startCluster, the actionhero is not crashing. But after few day, the periodic task is not working
Evan Tahler @evantahler Apr 11 21:53
whoa! I've never seen that. What node version + actionhero version + OS are you using?
@donnyhardyanto also a crazy idea: do you have any node-modules that have compiled extensions? ws comes to mind. If you do, delete them, turn those servers off, and try again
lets see if we can narrow this down to a specific module
I'll bet it's not a native js-only one
donnyhardyanto @donnyhardyanto Apr 11 22:10
OS: Ubuntu Server 14.0.4 LTS, NodeJS 4.4.2, Action Hero 13.2.3
donnyhardyanto @donnyhardyanto Apr 11 22:39
Correction: OS: Ubuntu Server 14.0.4 LTS, NodeJS 4.2.6, Action Hero 13.2.3
Sorry for mixup. For NodeJS 4.4.2, I just finish install Node 4.4.2 in another machine, preparing to test.
donnyhardyanto @donnyhardyanto Apr 12 00:57
Hi, has any one knows how to measure realtime TPS in action hero?
Evan Tahler @evantahler Apr 12 08:44
@donnyhardyanto that's more or less what I run in production... and I've never seen those crashes (or seen them reported anywhere else). I've got my money on a bad C plugin
TPS?
Transactions/per/second maybe?
if so, use the logs!
donnyhardyanto @donnyhardyanto Apr 12 09:20
Yes that TPS. How to use the log? is the timestamp at log line is the end of action or the start of action?
Evan Tahler @evantahler Apr 12 10:27
it's the end.
if you want to get really nuanced, you need request duration
you can make a middleware to return that (add data.response.StartOfRequest = new Date() and the equivielnt at the end of the request chain)
donnyhardyanto @donnyhardyanto Apr 12 10:28
I am still confuse about the formula of TPS, and how to calculate from start of request and end of request time.
Evan Tahler @evantahler Apr 12 11:36
TPS is a really bad metric for really anything in my opinion...
some requests are slow, some are fast
are you hitting the same "hello world" endpoint each time?
are you writing to a DB each time?
donnyhardyanto @donnyhardyanto Apr 12 11:50
not each time, only when there is business transaction
That right, so if only per day I can calculate the TPS because there is no transaction/request that span more than one day. But what happen if seconds or minutes. Some transaction might not finish at that point. So what is TPS?
Is it TPS at one point of time A is number of transaction finished in max 1 sec before A? So we dont include any not finished transaction.
Evan Tahler @evantahler Apr 12 13:13
it depends on saturation... that's why testing tools allow you to change the concurency. For example, if your request is hitting a CPU-bound action, the time each action takes will increase linearly with the number of requests. You can to 1TPS fixed as long as the concurancy is 1, but if you have a condurancy of 4, the TPS is 1/4
Chad Robinson @crrobinson14 Apr 12 13:54
@evantahler We tracked it down to a recent change in how i18n is handled by ActionHero. It seems in production mode it no longer generates locale files on its own - but still requires them to function properly. We temporarily fixed this by setting updateFiles: true in production but wondered if you had a different plan in mind.
Xotl @Xotl Apr 12 14:01
Hi everyone... just wanted to know if i can start actionhero from a different path. Let me explain, i want to run actionhero start /some/path/to/my/actionhero/folder, or something like that. is that even possible?
Chad Robinson @crrobinson14 Apr 12 14:25
Yes
command=/opt/newsrush/api/node_modules/.bin/actionhero startCluster --workerTitlePrefix api-
directory=/opt/newsrush/api
environment=NODE_ENV="production",ACTIONHERO_CONFIG="config,local-config",ACTIONHERO_TITLE="api"
autostart=true
autorestart=true
stopsignal=TERM
stderr_logfile=/var/log/api.err.log
stdout_logfile=/var/log/api.out.log
I use this in Supervisor.
But you can also set ACTIONHERO_ROOT and PROJECT_ROOT in your env.
Xotl @Xotl Apr 12 14:31
ok, thanks @crrobinson14... will try that
Xotl @Xotl Apr 12 14:41
one more question @crrobinson14 (or anyone), where's is that documented?
Xotl @Xotl Apr 12 14:48
... and BTW, the ACTIONHERO_ROOT variable didn't work, but PROJECT_ROOT did
Evan Tahler @evantahler Apr 12 17:05
@crrobinson14 the hard line localization people would say that you shouldn't allow any changes in prod, and that you should check in your words. That said I don't think a missing word should cause a crash :/
frankly, I'm not really sure if I have an opionon on it yet
@Xotl welcome!
@Xotl docs here => http://www.actionherojs.com/docs/#paths-and-environments
donnyhardyanto @donnyhardyanto Apr 12 17:12
@evantahler how to suppress logging of notification periodic task? Because periodic task is very 2 seconds, it just fill the log file with task end notification. I just need log when periodic task encounter error/exception.
Also in the end of periodic task, will calling next(err) will make periodic task will not be queue? (err is not null)
donnyhardyanto @donnyhardyanto Apr 12 17:19
and will the err is automatically logged (I dont have to call api.log)?
Muhamed Krlić @l0oky Apr 12 22:00
Has anyone tried making ZeroMQ workers in actionhero?
Or should I just use redis..
I plan to use It for a microservice architecture project
Muhamed Krlić @l0oky Apr 12 22:07
There's a huge performance difference
This message was deleted
Here's a better graph
http://blog.jupo.org/static/img/two-queues-3.png
source: http://blog.jupo.org/2013/02/23/a-tale-of-two-queues/
Muhamed Krlić @l0oky Apr 12 22:13
I am actually leaning towards redis, I am just wondering If anyone tried ZeroMQ with actionhero before
Chad Robinson @crrobinson14 Apr 13 07:41
@evantahler I don't know if I explained that very well - there are a lot of overlapping conversations here. The issue I was reporting was that suddenly my production boxes were emitted undefined for every log line. ActionHero depends on locale JSON files but only generates them if this flag is set to true. The thing is, we don't commit node_modules to Git. So this change to turn this flag off for production environments meant the files weren't getting created, but also weren't THERE because they weren't coming from anywhere else.
Muhamed, I haven't used ZeroMQ but I've used other stacks and there's really nothing you can't integrate easily. Redis is there for convenience because AH coordinates some of its own cluster activities through it, but you don't have to use it for your own work. You can make a simple initializer that loads an NPM and connects to anything you want, and exposes an internal API for that.
Xotl @Xotl Apr 13 08:53
thanks @evantahler
peterkingsbury @peterkingsbury Apr 13 09:23
@evantahler Looks like Jade updated (sidedated?) to a rename to Pug. Might need to update Mocha once they catch up.
Evan Tahler @evantahler Apr 13 09:44
@peterkingsbury is that causing problems?
@donnyhardyanto there are lots of logging options in config/tasks.
You can change the log levels to whatever you want
And correct, if you callback with an error, it will get logged
I don't think errors prevent the next run of a periodic task but I would have to check.
I think @crrobinson14 covered all I would want to say about reds vs *MQ
@l0oky
Evan Tahler @evantahler Apr 13 09:49
@crrobinson14 so did you not check in your locale folder?
Chad Robinson @crrobinson14 Apr 13 11:50
@evantahler No, of course not. I don't check in node_modules at all, let alone node_modules/actionhero/locale. By the way you're asking it sounds like AH should maybe be generating locale files in my main project folder... but it's not.
Evan Tahler @evantahler Apr 13 12:44
There it is! The locale files should totally be at the project top level!
So @crrobinson14 does api.config.general.paths.local = [__dirname + '/../locales']
Evan Tahler @evantahler Apr 13 12:50
IE: https://github.com/evantahler/actionhero/blob/master/config/api.js#L45
Chad Robinson @crrobinson14 Apr 13 14:45
Hmmm. I don't have that in my config file.
This message was deleted
Oops
paths: {
'action': [__dirname + '/../actions'],
'task': [__dirname + '/../tasks'],
'public': [__dirname + '/../public'],
'pid': [__dirname + '/../pids'],
'log': [__dirname + '/../log'],
'server': [__dirname + '/../servers'],
'initializer': [__dirname + '/../initializers'],
'plugin': [__dirname + '/../node_modules']
},
I would suggest that if a nested object block overrides a main level config setting that a deep-merge be performed instead of a straight copy/overwrite of the top level key. Because this obviously is making it so there IS no locale setting, and I didn't see that as a requirement to add anywhere during any of the upgrades I did.
Another option would be to catch it in the logger itself - if the locale is invalid it could just be caught/warned/tolerated there, probably only 1 typeof line of code would catch this with a graceful failure.
The first option would act more like the behavior in the rest of the config system, where core can define new keys that become the default unless the project overrides them. But it's also more code and could have some side effects, like deciding what to do if the user is overriding startingChatRooms
The second option just fails more gracefully and is very simple code, but only addresses this one use-case - it could come up again
Do you have a preference?
Krishna Glick @krishnaglick Apr 13 14:57
Atm when you upgrade ActionHero it's best to generate a new app somewhere and copy over the missing config parts.
donnyhardyanto @donnyhardyanto Apr 13 15:11
Yes @krishnaglick is right. I always do that. Generate new app, and incrementally copy actions, initializers and tasks. For config, I would very careful to check and compare the standard config files (api.js, tasks.js etc) line per line. That way so far no problem with upgrading.
donnyhardyanto @donnyhardyanto Apr 13 15:31
Hi has any one use Action Hero in High Availability scenario? My action hero api has periodic task, that cannot have more 1 instance running at same time. The trouble part is Redis. How do you setup Redis in HA environment?
Evan Tahler @evantahler Apr 13 15:59
@crrobinson14 upgrades in general are problematic... we certainly don't have a good way to do them now. I would prefer a "harsh" warning system... like have a list of config variables that must exist and crash if they don't
@donnyhardyanto running redis in HA is very easy
There are 2 methods to achieving HA redis: Sentinels and Cluster. I drew a simple architectural wireframe of how to deploy the various options (attached). First, the ioredis node package supports both of these connection schemes, and all you need to change is your connection options.
In Sentinel mode, you have your redis configured in a normal master->slave configuration. However, rather than hard-code your application to know who the master and slaves are, your application connects not to the redis master, but actually to any one of the sentinel processes. The sentinels processes transparently pipeline your connection to the proper master. What’s awesome is that in the event off a master failure, the sentinel processes reach a consensus, and elect a new master automatically. Since the same process which handles master election also manages the client connections, you actually never loose a request! The sentinels hold the connection idle and then replay your request on the new master after election. In the diagram I drew, you can loose any 2 redis data nodes, and any 1 sentinel and the system will still be up and running. The config options ioredis takes are a list of sentinels and the name of the cluster. They will round-robin requests though the sentinels, and in the event one is down, move on to the next one. you can run the sentinel nodes on the same servers as the redis data servers.
In Cluster mode, redis shards all the keys in data into “slots” which are evenly allocated though all the masters in the cluster. The client can connect to any node in the cluster, and if the requested key belongs on another node, it will proxy the request for you (just like the sentinel would). The cluster can also take care of master re-election “for each shard” in the event of a master node failure. Cluster mode takes the HA features of sentinels, and adds the ability to store more data in the cluster. You’ll end up needing slightly more servers for cluster mode though (min 3 vs min 6) to get the quorum working and have redundancy.
Also an important note: while you may opt to run “sentinel processes”, it’s the same codebase as regular redis, just running in “sentinel mode”. The same goes if you run redis in “cluster mode”.
Krishna Glick @krishnaglick Apr 13 16:01
@evantahler Works for me. The locale stuff threw me off the first time I upgraded and it would def be nice to have a hard stop when you start AH vs at some point during operation.
Evan Tahler @evantahler Apr 13 16:01
@krishnaglick @crrobinson14 pull requests welcome :D
Krishna Glick @krishnaglick Apr 13 16:02
Haha, I'll have to dig in at some point.
donnyhardyanto @donnyhardyanto Apr 13 16:09
Tanks @evantahler, what is minimum number of server for sentiner configurations? I have only max 3 servers for everything (including db, redis etc)
Can 3 servers handle that?
Evan Tahler @evantahler Apr 13 16:10
I can't tell you if you should run more than one process per server, but I can say that for the leader-election algorithm to work, you need at least 3 servers running sentinels, yes
Chad Robinson @crrobinson14 Apr 13 18:41
@evantahler evantahler/actionhero#819 posted with your Redis comments above, give or take a bit of copy-editing. I thought they were super useful and justified some documentation.
I've never edited gh-pages in a fork before, couldn't figure out how to test that well. Let me know if I did anything wrong. Github complains that the CNAME for the site is already taken and I can't view it properly in my own fork.
Evan Tahler @evantahler Apr 13 19:30
Thansk @crrobinson14, I fixed your PR here -> evantahler/actionhero#821
To edit GH pages, you can run the whole thing locally! check out the sub-readme for it -> https://github.com/evantahler/actionhero/tree/master/site
donnyhardyanto @donnyhardyanto Apr 13 23:11
Hi @evantahler. Because when I stop the api, most of the time the periodic task resque is locked. I tried to run redis-cli KEYS “resque:*" | xargs redis-cli DEL
It delete all the key under resque except one: "resque:timestamps:{\"class\":\"processReservationQueueTask\",\"queue\":\"processReservationQueueTask\",\"args\":[{}]}”
I have to delete it using Delete Branch using Redis-Commander, otherwise when I started the api, the periodic task will not start again
Do you know how to delete all resque:* cleanly? Or is there any other ways to remove the lock?
Evan Tahler @evantahler Apr 14 03:09
If you are deleting everything, use flushdb
Chad Robinson @crrobinson14 Apr 14 07:37
To support what you guys are talking about above, I put my resque stuff in DB1 and my other AH cluster stuff in DB0. That way I can flushdb to clear resque and not affect anything else. I'm still tracking down issues in my task management stack.
Thanks for fixing the PR, Evan
I didn't see the site/README.md because I wasn't familiar with the structure there. Suggestion: put a reference to it in the root/README.md file?
Jose Bueno @jrbueno Apr 14 08:23
Hi, I'm using actionhero with Ember in the frontend using Ember-Data. is there a way to overwrite the response payload to output errors: {} instead of error:{}?
Evan Tahler @evantahler Apr 14 13:48
@crrobinson14 done evantahler/actionhero@173fd70
@jrbueno not really.... open an issue for it! We are 1/2 the way there with the error serializers in cofig/errors, but you can't change the key
so you can end up with error: [], but not errors: []
@jrbueno or better yet, send in a PR for it! Add another option to that serializer hash for "errorKey" or something like that, and change the 3 server types to acccet it
Jose Bueno @jrbueno Apr 14 13:56
@evantahler I realized that looking at the source. I will work on it and submit a PR. thanks!
Chad Robinson @crrobinson14 Apr 14 18:20
For any newcomers out there reading this, the discussion above is one of the things I love about ActionHero. Having a fast-evolving core is a big advantage. There's always SOMETHING you find lacking in any framework. The best are approachable and welcoming in those situations.
Evan Tahler @evantahler Apr 14 18:29
:smile:
Chad Robinson @crrobinson14 Apr 14 19:08
AH runs really well in containers / Docker, in case anybody is curious. Since it was designed from the ground up to be horizonally-scaled / cluster-aware, it just drops straight into most Docker strategies.
I'm running it in Rancher but Kube/Mesos are fine too
Evan Tahler @evantahler Apr 18 06:57
neat.
Israel Tiomno @tiomno Apr 18 21:59
Hello everybody,
I'm brand new to Node and very happy to start with actionhero.js!
Would anyone give me a clue about how to get access to the api.connection.localize method from input validator callback function?
From action.run it's easy since the first and second parameters are the api and data objects. :)
Thank you.
P.S. Thanks for the info @crrobinson14 , I'll give it a go.
Evan Tahler @evantahler Apr 19 03:57
Api = this in the validators. I think you can also call connection.localize
peterkingsbury @peterkingsbury Apr 19 06:15
@evantahler I don't think the jade(pug) -> mocha -> AH thing is particularly impacting, just noticed it and wanted to bring it up here.
@evantahler Do actions support variably-named parameters? e.g. if I want users to be able to send GET http://ip:port/api/someAction?someArrayKey[someArrayIndex]=someValue via GET/POST, and someArrayIndex is not a static string but could be any alphanumeric string?
Evan Tahler @evantahler Apr 19 07:52
No, you would have to name the input, like "data". If you post JSON it will serialize properly.
Oh, actually your example might work with options on the query parser.
Israel Tiomno @tiomno Apr 20 14:40
Thanks @evantahler.
donnyhardyanto @donnyhardyanto Apr 21 02:53
Hi @evantahler, I have installed redis-sentinel, and change port on redis.js to 26379. When I start the action hero, there is error:
2016-04-21T09:50:10.459Z - notice: *** starting actionhero *** Unhandled rejection ReplyError: ERR unknown command 'publish' at ReplyParser._parseResult (/app/parkirin-api/1.3/node_modules/ioredis/lib/parsers/javascript.js:39:14) at ReplyParser.execute (/app/parkirin-api/1.3/node_modules/ioredis/lib/parsers/javascript.js:139:20) at Socket.<anonymous> (/app/parkirin-api/1.3/node_modules/ioredis/lib/redis/event_handler.js:94:22) at emitOne (events.js:77:13) at Socket.emit (events.js:169:7) at readableAddChunk (_stream_readable.js:153:18) at Socket.Readable.push (_stream_readable.js:111:10) at TCP.onread (net.js:531:20)
and the periodic task is not running. What is wrong?
Evan Tahler @evantahler Apr 21 07:02
Share your whole config?
donnyhardyanto @donnyhardyanto Apr 21 08:11
redis.js
tasks.js
redis.conf
sentinel.conf
@evantahler, those are the config files.
Evan Tahler @evantahler Apr 21 09:51
@donnyhardyanto the config style changes when using sentinel
https://github.com/luin/ioredis#sentinel
so you want something like this
exports.production = {
redis: function(api){
return {
channel: 'actionhero-app',
rpcTimeout: 5000,
pkg: 'ioredis',
port: null,
host: null,
password: 'password',
database: 1,
options: {
name: 'MY-CLUSTER',
password: 'password',
db: 1,
sentinels: [
{ host: '1.2.3.4', port: 26379 },
{ host: '5.6.7.8', port: 26379 },
]
}
}
}
}
donnyhardyanto @donnyhardyanto Apr 21 10:06
ooh. ok.
It is missing in doc? Or I miss something in docs?
ooh. it the config for sentinels in options
I guess I miss read that section in IORedis. Thanks @evantahler .
Evan Tahler @evantahler Apr 22 17:40
@krishnaglick, @peterlandry, @synthmeat , @ndcollins, @crrobinson14 , @bluesunrise, @l0oky, @dangerdespain, @omichowdhury I'm trying something new starting at actionhero v13. I got some stickers... you all get one for contributing! Email me at evan@evantahler.com with your address and I'll mail you some. The only caveat is that you need to stick it somewhere and tweet back a photo :D
Evan Tahler @evantahler Apr 22 17:50
one more photo:
Chad Robinson @crrobinson14 Apr 22 19:11
Nice!
I'll ping you via email.
Muhamed Krlić @l0oky Apr 23 08:31
Awesome :D
Muhamed Krlić @l0oky Apr 23 08:41
@evantahler Does socket server really use ^] delimiter?
Evan Tahler @evantahler Apr 23 08:42
No? It's carrage return
Muhamed Krlić @l0oky Apr 23 08:43
Took me some time to figure, when you do telnet localhost port it says delimiter is ^]
ooh that means carriage return?
ill do a PR where you can choose the delimiter yourself?
I literally took the string ^] as a delimiter and tcp server didn't recognize the message. Could be a potential memory leak as connection.rawConnection.socketDataString is just filling.
Sebastian Dechant @S3bb1 Apr 23 09:16
nice stickers @evantahler ! will you sell them too ? :D
Evan Tahler @evantahler Apr 23 09:51
@l0oky cool, The dynamic delimiter would be needed in these lines https://github.com/evantahler/actionhero/blob/master/servers/socket.js#L118-L130
@l0oky if you also want to add a config option for max socketDataString, that sould be cool too... and set the defuault to Infinity to be backwards compatible
@S3bb1 absolutely! https://www.stickermule.com/marketplace/8033-actionherojs
I'll add that to actionherojs.com
Evan Tahler @evantahler Apr 23 10:11
Ok! You can get your tshirts and stickers from the website now :D evantahler/actionhero#822
Sebastian Dechant @S3bb1 Apr 23 11:04
nice one! :D
Muhamed Krlić @l0oky Apr 23 23:00
I really wish we marry actionhero with c++ modules :D
Would that affect cross compatibility? I think not?
Evan Tahler @evantahler Apr 23 23:16
I mean... There's no reason to do that in the core?... Feel free to make modules!
Muhamed Krlić @l0oky Apr 23 23:19
I was just thinking about it, nodejs is good for parallel work. Sometimes you just need performance in some parts :) Although I am just speculating here, no real proof :D
Evan Tahler @evantahler Apr 24 00:47
Cluster.fork.
Evan Tahler @evantahler Apr 24 10:44
@all If you write a post on medium about actionhero, please use the tag "actionherojs" so we can start collecting stories. Thanks! https://medium.com/search?q=actionherojs
Evan Tahler @evantahler Apr 24 12:35
anyone else here have a Tessel? https://medium.com/@evantahler/actionhero-tessel2-35ef36291d0b#.ozz6cdsk1
n-s-k @n-s-k Apr 24 12:41
@evantahler @l0oky I have a dream: Tessel + AH + easy-to-bind C++ modules :smile:
Muhamed Krlić @l0oky Apr 25 09:37
Oh My God. That is so cool!
@evantahler What's the message format when client is receiving an error?
var error = api.config.errors.dataLengthTooLarge(api.config.servers.socket.maxSocketDataLength,blen);
server.log(error, 'error');
server.sendMessage(connection, {status:'error', error: error, context: 'response'});
{status:'error', error: error, context: 'response'}?
peterkingsbury @peterkingsbury Apr 25 11:02
I don't suppose a 4-node AH cluster running on stacked Pi's is of much interest? :D http://postimg.org/image/8x9z59nef/
Muhamed Krlić @l0oky Apr 25 11:08
:tongue: that is really cool
What's the benchmark??
Evan Tahler @evantahler Apr 25 11:47
@l0oky seems fine to me
Muhamed Krlić @l0oky Apr 25 11:47
Great :)
Evan Tahler @evantahler Apr 25 11:47
@peterkingsbury (and @l0oky) you both better write some blog posts
try medium out... it's pretty easy
Muhamed Krlić @l0oky Apr 25 15:40
I would like to research actionhero + docker a bit. But I have an issue, docker is only for 64bit and I am running i386 debian
Also tbh, never tried I Workers in actionhero. Tasks too. Can't wait to dive in
Sebastian Dechant @S3bb1 Apr 28 02:11
@evantahler what is the reason for the actionhero link function to copy the config directory instead of creating a link file for that ?
Evan Tahler @evantahler Apr 28 08:35
Because you are expected to modify those files.
And not the actions/initializers/etc
Sebastian Dechant @S3bb1 Apr 28 09:12
Mh but for now when a plugin includes custom Routes the file has to be prefixed.
Evan Tahler @evantahler Apr 28 09:44
well, it gets even weirder... what if you have some routes in your main project, and there are some routes in your plugin... I don't think you have 2 routes files
it's A) up to the user to merge them all
or B) the plugin can modify the routes hash directly
IE: http://www.actionherojs.com/docs/#plugin-methods
if you know the route won't conflit
(usually a namespace is safe)
Evan Tahler @evantahler Apr 28 09:59
@S3bb1 I guess to handle the case you are working on, we might need a routes 'folder'
within config
Sebastian Dechant @S3bb1 Apr 28 10:12
Yeah that would it be. Because in our projects we have all Routes namespaced and we have about 5 or more Plugins in a project so a user merge would be time intensive. Or we have to build a build Task which would merge them
Evan Tahler @evantahler Apr 28 11:25
that's why for now I think having the plugin explicitly handle the routes is probably the way to go
Sebastian Dechant @S3bb1 Apr 28 22:49
so you think the best practice is that the plugin should register the routes with the api.routes.registerRoute method and not with a routes.js file ?
Evan Tahler @evantahler Apr 29 07:02
For now, yes.
Muhamed Krlić @l0oky Apr 29 12:21
Does AH socket server handle utf-8 well?
Evan Tahler @evantahler Apr 29 13:28
Should be? Node.js in generall is pretty great about UTF8 (which is the default encoding)
and we are coercing all buffers to strings via UTF8 anyway https://github.com/evantahler/actionhero/blob/master/servers/socket.js#L131
Evan Tahler @evantahler Apr 30 13:06
New Release!
https://github.com/evantahler/actionhero/releases/tag/v13.3.3
Dynamic line delimiter and maxDataLength (Socket Server)
added a api.config.servers.socket.delimiter option to the socket server so you can change from \n being the line delimiter.
adding a api.config.servers.socket.maxDataLength option to the socket server to prevent buffer overflows with long data submissions
By @l0oky via evantahler/actionhero#824
Expose matched route to Connection
now you can check data.connection.matchedRoute to see the details of the route that got the web connection to this action... if in case a route was matched via the router.
data.connection.matchedRoute = {
path: '/mimeTestAction/:key',
matchTrailingPathParts: false,
action: 'mimeTestAction'
}
By @evantahler via evantahler/actionhero#825
Generator
Fixed a line break stopping "use strict"; from kicking in for generated actions evantahler/actionhero@2c07d2a
Adding "ceateChatRoom" to newly generated projects so that the websocket example works evantahler/actionhero@9e61ee8
Documentation Updates
How to handle crashes and defensive coding evantahler/actionhero@c00a600
Guide to redis High Availability: evantahler/actionhero#821
Notes on how to update the documentation evantahler/actionhero@173fd70
Adding links to actionhero shirts/stickers evantahler/actionhero#822
Chad Robinson @crrobinson14 May 02 20:28
Nice!
@evantahler What's the pattern you'd recommend for generating a plain-jane raw response with a header and no body? I need to emit a 302 redirect but with no body and a content-type of text/plain for a third-party app. (But it's a real API call with params, not a static page or anything - I want this inside the stack, so to speak.) I'd normally res.writeHead and res.end but I want to make sure what I do doesn't conflict with what AH does internally after the action returns.
Chad Robinson @crrobinson14 May 02 20:35
I went with this and it does the job, but is it the best way?
data.toRender = false;
data.connection.rawConnection.res.writeHead(302, {
Location: zencoderUrl,
'Content-Type': 'text/plain',
'Content-Length': '0'
});
data.connection.rawConnection.res.end();
Sebastian Dechant @S3bb1 May 02 22:22
@crrobinson14 maybe you can set
data.connection.rawConnection.responseHttpCode = 302;
data.connection.rawConnection.responseHeaders.push(['Content-Type', 'text/plain']);
data.connection.rawConnection.responseHeaders.push(['Location', zencoderUrl]);
data.connection.rawConnection.responseHeaders.push(['Content-Length', '0']);
next();
so actionhero handles the webserver response to the client.
Evan Tahler @evantahler May 03 13:01
Yep, @S3bb1 has it!
I think you can skip the content-length one as well
Israel Tiomno @tiomno May 04 22:27
I'm creating an initializer to use in an action middleware so I can validate a signature (HMAC SHA256 hex digest) for the HTTP request.
Is accessing the following the best way to get the raw querystring?
data.connection.rawConnection.parsedURL.search
module.exports = {
initialize: function(api, next) {
api.signature = {
authenticate: function(data, next) { // passing data here
var self = this;
var error = null;
var querystring = data.connection.rawConnection.parsedURL.search; // ??
// parse querystring and validate the signature ...
next(error);
}
};
next();
}
};
Thanks.
Don Park @donpdonp May 05 09:42
inside an action im doing a simple api.redis.client.set('lookhere', 'value'), yet when I check from redis-cli, the key 'lookhere' is nil. any ideas?
ive put a console.log msg that verified the action is being called
actionhero overall is fantastic, thanks for the software!
Sebastian Dechant @S3bb1 May 05 09:45
@donpdonp do you put a callback into the client.set function and checked that no error occured ?
Don Park @donpdonp May 05 09:46
i have not. im actually noticing that 'fakeredis' is in use
how can I get to 'real' redis? :)
Sebastian Dechant @S3bb1 May 05 09:47
ah okay, because with fake redis you can not look into the data with redis-cli
fake redis is a in memory redis "fake" which runs as nodejs module
you can change the config/redis.js file
and change these settings https://github.com/evantahler/actionhero/blob/master/config/redis.js#L9 to "ioredis" and pass your connection details
or set the environment vars mentioned in the redis.js config
Don Park @donpdonp May 05 09:50
i see it. thanks!
Don Park @donpdonp May 05 12:25
another question: im trying to create a route with /api/v1
{ path: '/v:apiVersion/status', action: 'status' }
that doesnt work as expected. /:apiVersion/status works fine for /api/1/status
Evan Tahler @evantahler May 05 15:42
@tiomno yep, that's fine!
you can also get data.connection.rawConnection.res if you want the raw node connection object
This message was deleted
nice @S3bb1
@donpdonp our route parser doesn't have support for partial statments in the route sub-section (like /v:apiVersion/). Open up an issue on github if that's something you need
Israel Tiomno @tiomno May 05 16:42
Thank you @evantahler.
Evan Tahler @evantahler May 05 20:36
https://twitter.com/actionheroJS/status/728427871614566404
Sebastian Dechant @S3bb1 May 05 20:42
Nice @evantahler node.js 6 now supports up to 98% ES6!
Israel Tiomno @tiomno May 05 20:45
:+1:
Israel Tiomno @tiomno May 05 20:51
Does mocha + blanket seem sound for unit tests and code coverage in actionhero?
Evan Tahler @evantahler May 05 21:22
we happen to use mocha + istanbul in actionhero's core
but sure, that's a fine choice
I don't personally have any strong opinions either way
@/all do y'all have any opinion about keeping this group here in Gitter or moving to Slack?
Israel Tiomno @tiomno May 05 21:29
I love slack. We use it in our company. The only concern would it be: https://medium.freecodecamp.com/so-yeah-we-tried-slack-and-we-deeply-regretted-it-391bcc714c81#.i6o5e9bqy But maybe that's not true anymore or not a concern for this group.
Evan Tahler @evantahler May 05 21:42
I think they fixed a lot of things
and with http://rauchg.com/slackin, it makes joining pretty easy
I don't pre-se have any problems with gitter, it's just another option
Israel Tiomno @tiomno May 05 21:44
Well, count me in!
Israel Tiomno @tiomno May 05 22:50
istanbul cover ./node_modules/mocha/bin/mocha --no-colors
is getting me: No coverage information was collected, exit without writing coverage information so I don't know how to integrate istanbul with mocha.
Mocha is running the tests withotu problem. :(
Israel Tiomno @tiomno May 05 23:13
istanbul cover ./node_modules/mocha/bin/_mocha --no-colors done. :)
Neil Craig @neilstuartcraig May 06 06:56
@evantahler - i’m on slack at work all day so would probably be more likely to join in…been busy recently with a project but would like to contribute to AH more in the future
omichowdhury @omichowdhury May 06 11:47
The only issue would be keeping a searchable history since free Slack channels only keep the last 10k messages
Evan Tahler @evantahler May 06 13:08
I personally think that is fine... anything worth keeping should end up on the wiki anyway
any more thoughts @/all?
Greg Coonrod @gcoonrod May 06 13:49
@evantahler: evantahler/actionhero#830 This is meant to be a fun little demo. We're not at all interested in merging this code.
donnyhardyanto @donnyhardyanto May 06 14:28
Why must move to Slack?
Evan Tahler @evantahler May 06 17:41
@donnyhardyanto we certainly don't have to. Just discussion options. For me, the feature set is more-or-less equivalent. Many folks already seem to use Slack every day at work, so having "one less tool" might be nice.
@gcoonrod madness :D
I've got some projects that have an action to git pull, and then kill themselves off (to be rebooted with new code from the cluster manager)
Greg Coonrod @gcoonrod May 06 18:15
@evantahler we're still trying to figure out how to utilize the functionality we created along with AWS beanstalk to manage the upgrade of an entire cluster of AH servers.
Evan Tahler @evantahler May 08 12:16
[Evan Tahler, actionherojs] Hello from slack
Hello from gitter
omichowdhury @omichowdhury May 09 07:59
Slack +1 from me
Don Park @donpdonp May 09 09:23
how can i get a second redis client while inside an action, to listen to a pubsub channel?
Evan Tahler @evantahler May 09 09:25
@omichowdhury @donnyhardyanto @neilstuartcraig I just tried a service, sameroom.io which proproted to "link" slack and gitter. It works for content, but you loose the metadata, like who-said-what, etc. I think we'll need to pick one. Can you share why you like slack better?
@donpdonp you have both api.redis.client and api.redis.subscriber https://github.com/evantahler/actionhero/blob/master/initializers/redis.js#L33-L40
if that is what you want
Don Park @donpdonp May 09 09:27
oh, subscriber is available for use? great. i thought it might be something internal
Israel Tiomno @tiomno May 09 16:55
What I like about Slack is the neat UI and that you can have different channels per topic|category|project|country|music|language or for whatever sorting you want to apply to them.
We might have a channel integrated to GitHub to track changes to AH and comments on commits.
Another channel might be related to deployment and environment production.
Another for general questions like what we mostly do in this room.
Another for new ideas, plugins and integration with AH.
Another for saying thanks https://about.gitlab.com/2015/04/08/the-remote-manifesto/#give-credit-where-its-due-and-remember-to-say-thank-you
You name it. ;) I'm not good organising things, but I'm sure this can give you ideas of how to get the info you need quick and easier.
The search is better than gitter's. Desktop, iOS and Android apps work like a charm.
Slack has cool options for the chat: upload file, create a snippet in 59 languages (we probably used 4 or 5 ;)), pin important messages. And some funny like adding your custom emoji and programming the slack bot to react to certain phrases. Integration is an important part of Slack project with a big list of apps and services, although creating your own is not a big deal.
The rest of the features are there, but I usually don't use them or don't know that exist. :)
Evan Tahler @evantahler May 09 18:40
Well... I guess we should put it to a vote?
Israel Tiomno @tiomno May 09 18:41
Slack +1
Evan Tahler @evantahler May 09 18:42
I'll abstain, so I don't bias anyone I'll be the tie-breaker if needed
salles @sallespro May 09 19:04
i use slack, and like it a lot because of the integrations. this is a context related to spliting each project into a feed where you can invite people in, single purposefully. i also value gitter’s simplicity, framework related single feeds is my use case. i miss a single diferentiation feature in gitter, but i am here with people, who chose the tool to host AH’s conversations.
salles @sallespro May 09 19:12
maybe if the community goes to slack, which has an unavoidable feeling, i’ll be there because of you, not really Slack, but i like Slack and it will be a good thing. but it feels also good to be A(nti)H(ero) and remain with the weak, not the best, a minority if what we’re looking is not to be at the best side of anything, just our side.
and maybe we should be fair to let gitter know what would hinder us not to make it what we want it to be, if we’re into the chatty playgrounds.
salles @sallespro May 09 19:20
and Maybe we should have our own thing, as a way to make AH already pretty good primus/chat basis “Evan” better, and integrate all around to make of us a plugin hero.
or we can just choose another tool and chat with emojis all around just for fun.
salles @sallespro May 09 19:30
AH and Evan’s availability have taught me a lot with his elegant code structure and i am very thankful to it. i follow the discussion and learn about the production environments, here, i haven’t felt like able to contribute, except with ideas and questioning the people we happen to engage with.
Israel Tiomno @tiomno May 09 19:38
Good on you @sallespro. That's important for an open source community imho. I just ask silly questions in this room.
But I still prefer Slack until we "have our own thing, as a way to make AH already pretty good primus/chat basis “Evan” better, and integrate all around to make of us a plugin hero." ;P
MarkPareja @MarkPareja 00:43
@evantahler Slack +1 & gitter +1, I've already written many AH based slack integrations such as scheduled messages, bots (w/ Knwl.js natural language parser) , slack-channel <-> ah-chat bridge. Mostly because we use slack at the shop, I have yet to build anything against gitter.im but I'm going to start hitting it soon, as the rest and streaming api are not too dissimilar to slack's. I would suggest not create yet another dev-centric IM platform, but leverage AH and the power of your framework to bridge everything together and let the people choose which client they prefer. Yes I'm referring to using AH to bridge Gitter-room/Slack-channel/AH-chat together, and for kicks add a realtime feed to the documentation page @ actionherojs.com . #ambitious
Muhamed Krlić @l0oky 15:19
Why not slack I don't mind moving. Gitter app on my phone is bugged anyways :)
(frontend) https://github.com/l0oky/meni.js Dynamic Menus, why not? I appreciate any comment :)
Evan Tahler @evantahler 18:22
@l0oky coolio.
so... only 3 people voted?
This message was deleted
This message was deleted
@omichowdhury @neilstuartcraig @crrobinson14 any thoughts?
@MarkPareja there's already a chat button on the actionhero docs! It's Gitter!
Chad Robinson @crrobinson14 18:31
@evantahler Sorry I've been traveling. I enjoy Slack - I use it for like 6 other discussions. I'd certainly check in more frequently. I don't run gitter all the time, but I run Slack all the time
Israel Tiomno @tiomno 19:45
Can anyone give me a hint on how to configure forever to run actionhero?
My project is in /var/www/api
I have a forever.json with this content:
{
// actionhero.js API deamon
"uid": "baldur",
"append": true,
"watch": true,
"script": "actionhero",
"sourceDir": "/var/www/api/node_modules/actionhero/bin",
"workingDir": "/var/www/api",
"args": ["start"]
}
And I'm runnig forever like this forever start -l forever.log -o forever-out.log -e forever-error.log ./forever.json
But getting this in forever-error.log:
Error: No config directory found in this project, specified with --config, or found in process.env.ACTIONHERO_CONFIG
So, I'm not telling forever how to create the environment correctly for actionhero. :(
Thanks
Evan Tahler @evantahler 20:39
So that's now 4 to 1 in favor of slack...
@tiomno I never use forever, but here's a PM2 writeup whcich might help https://gist.github.com/slattery/0fd0ce6e62f6fb185ea9
Nick Collins @ndcollins 21:07
+1 for slack
Evan Tahler @evantahler 21:15
5 to 1 for slack
on a related note... I can't seem to find any gitter export tools
we may loose all the contet here :/
Nick Collins @ndcollins 21:20
Why not leave Gitter open for X number of weeks with an automated post each day to remind people to change to Slack. That should give ample time for people to move, then if there is a way to leave the archives of the room available while disallowing new posts, you could close it off then.
Evan Tahler @evantahler 21:21
I worry that people will get confused. I know folks that just search here for open source projects
and I don't think that there is a "READ ONLY" mode
if there were, that would work
I'm personally not too sad about loosing the history though
anything important should have made it into the docs... in theroy
Nick Collins @ndcollins 21:23
Indeed
Israel Tiomno @tiomno 21:28
Thank you @evantahler! I'll give pm2 a go!
Muhamed Krlić @l0oky 22:11
@evantahler just change the description with the link to slack
Muhamed Krlić @l0oky 22:22
assuming that it is possible
Evan Tahler @evantahler 22:23
yah, it is
setting things up now
Evan Tahler @evantahler 22:31
so yeah.
i guess its time
Muhamed Krlić @l0oky 22:31
3
2
Evan Tahler @evantahler 22:31
slack.actionherojs.com
Muhamed Krlić @l0oky 22:32
1
oh I am late
Evan Tahler @evantahler 22:32
@/all WE ARE SHUTTING DOWN THIS GITTER ROOM. EVERYONE MOVE TO SLACK => slack.actionherojs.com
Evan Tahler @evantahler 22:37
@/all I'll keep this channel open for a few days for legacy, but then I'm shutting it down
THIS CHANNEL IS CLOSED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment