Comments (10)
That is very strange. Motion does keep a cached copy of the component around in the channel, but that should be released by ActionCable when the subscription is removed by the client (This is done so that the client doesn't have to send the state back up to the server past the initial mounting).
Also, I wouldn't expect this object to be particularly large. A marshalled representation of it is in the client's markup, after all. It is usually on the order of hundreds of bytes.
@dannyvanhoof Why do you think that Motion is leaking memory?
from motion.
The only other longer-lived piece of state created by Motion (besides the configuration and a few service objects) that I can think of is a renderer for the websocket connection. This should only live as long as the client is connected though -- it is actually stored on the connection object itself.
from motion.
Alec - we're just in the early stage of our investigation. Since we started using ViewComponents + Motion, we saw our memory usage on Heroku rising, and were thrown out couple of times. Early this week I added the gem_process_mem gem to our application, and started looking at the memory usage (production) at the end of loading a page (after starting garbage collection manually), and again after closing the tab on the browser. That's when I noticed that loading a page containing VC + Motion increased the memory used, and it didn't go down after closing the tab. But clearly, this will need more investigation.
from motion.
Update: we checked the size of the marshalled objects on the client side, and for some of our pages we found like 240 VC's, each with 30Kb data. Instead of storing the object as instance variable in the VC, we now store the object's id. This reduced the data on the client side to 240 x 30 bytes. The page itself also loads much faster now, and we see a much smaller increase in memory. I guess I'll stop the investigation as for now. What I learned from this: don't store the object itself as instance variable - unless it's really very small...
from motion.
I think an intermittent failure that occurred on CI this morning might be related (unfortunately, I retried and that seems to have erased the logs). It was an exception from within ActionCable saying that it could not find a subscription to remove.
When I get some more time, I'll dive into that.
@dannyvanhoof State size is a known pain-point in Motion. We have plans to support server-side state with Redis or Memcached which would significantly cut down on the amount of data over the wire, but that has yet to be implemented.
from motion.
Ah, it happened again. I won't retry the job this time: https://travis-ci.com/github/unabridged/motion/jobs/383344606
from motion.
@dannyvanhoof State size is a known pain-point in Motion. We have plans to support server-side state with Redis or Memcached which would significantly cut down on the amount of data over the wire, but that has yet to be implemented.
Alec - wouldn't it be an idea to allow for instance variables that could be excluded from being marshalled? this way, we could use the original object to render the first time, but not marshall it, and marshalling the object's id instead. So a first rendering could use the original object (preventing an n+1), while an update would first have to retrieve that object.
from motion.
@dannyvanhoof If you have some time, I'm curious if 0.4.3
fixes the memory leak that you were noticing.
wouldn't it be an idea to allow for instance variables that could be excluded from being marshaled?
I'm open to this, but I think it is a band-aid for a couple of deeper problems that I want to address. I think the right combination of optimized marshaling implementations for common libraries (like ActiveRecord), server-side state (so there are fewer bytes in the DOM and over the wire), and something like Phoenix LiveView's DOM patching (which would enable the ability to have arbitrarily long lists without storing every item in state) can solve this in a way that the user does not need to worry about which ivars are being serialized.
If something like this is added to Motion, I think it should look like:
def dump_state
[@ivar, @another_ivar]
end
def load_state(state)
@ivar, @another_ivar = state
end
from motion.
Alec, yesterday we had again a problem during our rspec tests on wercker, I guess related to what you mentioned above. Version 0.4.3. I'm copying the entire error below. Does this ring a bell? Context: we render a component including motion, fill in an input field in that component, then push a button in that component triggering a motion event. Somehow the entire "system" is not fast enough, unless we put in some sleeps in the rspec test...
E, [2020-10-28T16:31:22.176498 #1392] ERROR -- : Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"Motion::Channel\",\"version\":\"0.4.0\",\"state\":\"292U0RV/3art6rR/ ... 4ig=="}]: /pipeline/cache/bundle-install/ruby/2.7.0/gems/actioncable-6.0.3.4/lib/action_cable/connection/subscriptions.rb:74:in
find' | /pipeline/cache/bundle-install/ruby/2.7.0/gems/actioncable-6.0.3.4/lib/action_cable/connection/subscriptions.rb:55:in perform_action' | /pipeline/cache/bundle-install/ruby/2.7.0/gems/actioncable-6.0.3.4/lib/action_cable/connection/subscriptions.rb:19:in
execute_command' | /pipeline/cache/bundle-install/ruby/2.7.0/gems/actioncable-6.0.3.4/lib/action_cable/connection/base.rb:87:in dispatch_websocket_message' | /pipeline/cache/bundle-install/ruby/2.7.0/gems/actioncable-6.0.3.4/lib/action_cable/server/worker.rb:59:in
block in invoke'
`
from motion.
Tests interacting with motion tend to be unstable because of a race condition. This is an example where we redirected the browser log to Rails logger have a better understanding of events.
D, [2020-10-30T08:21:08.954247 #1424] DEBUG -- : [Browserlog] [Motion]
D, [2020-10-30T08:21:08.954374 #1424] DEBUG -- : [Browserlog] Connecting component
I, [2020-10-30T08:21:09.000870 #1424] INFO -- : Started GET "/cable" for 127.0.0.1 at 2020-10-30 08:21:09 +0000
I, [2020-10-30T08:21:09.090864 #1424] INFO -- : Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2020-10-30 08:21:09 +0000
I, [2020-10-30T08:21:09.091058 #1424] INFO -- : Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
D, [2020-10-30T08:21:09.124281 #1424] DEBUG -- : [Browserlog] [Motion]
D, [2020-10-30T08:21:09.124420 #1424] DEBUG -- : [Browserlog] Processing motion
D, [2020-10-30T08:21:09.124508 #1424] DEBUG -- : [Browserlog] scan
D, [2020-10-30T08:21:09.124583 #1424] DEBUG -- : [Browserlog] on
I, [2020-10-30T08:21:09.204965 #1424] INFO -- : [ScanReturnItemsComponent:421200] Connected (in 1.8ms)
D, [2020-10-30T08:21:09.291677 #1424] DEBUG -- : [Browserlog] [Motion]
D, [2020-10-30T08:21:09.291817 #1424] DEBUG -- : [Browserlog] Component connected
It seems a motion is processed even before the component is connected? Which seems weird given the _subscription gets set once the component is connected.
motion/javascript/Component.js
Lines 23 to 31 in 90308c4
and
motion/javascript/Component.js
Lines 39 to 45 in 90308c4
In this case, the processing of the motion seemed to work, but the rerender never happened failing the test. We also see the Could not execute command
error following Unable to find subscription with identifier
. The order of the log messages are similar in that case: a motion seems to trigger before the "connected" event.
We see that you use system test helpers to make sure to wait long enough. I guess that originates from the same problem?
from motion.
Related Issues (20)
- Motion does not work on older IOS versions
- Motion v0.5.0 does not work with ViewComponent >= v2.35.0 HOT 1
- Demo site does not load, errors out HOT 2
- [Question] What's the purpose of data-motion-key and -state? HOT 3
- [Question] Preventing unauthorized access to a resource's stream HOT 2
- It doesn't seem that Motion supports passing in a form builder object. HOT 1
- [Discussion] Debouncing input and the mystery of event targets HOT 8
- Slow application startup times in some projects HOT 24
- `session`, `cookies`, and `current_user` are only accessible while rendering HOT 5
- Motion component is unable to have a handle to a form object HOT 7
- Transpiled Event Serialization Issue HOT 1
- Add test helpers for generating events for testing
- Custom element attributes are lost on component re-render
- Events capture HOT 1
- [question] broadcast to multiple clients HOT 3
- Compatibility issue with Rails 6.1 ? HOT 12
- Domain lost after page change HOT 4
- Add better support for custom logging HOT 2
- Documentation: Clarify that info from request is lost after first re-render HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from motion.