-
-
Notifications
You must be signed in to change notification settings - Fork 237
Replace Multiple Stores with Multiple FS.Collections #182
Comments
Not sure what this solves / motivation - maybe we should have a hangout to discuss the overview? |
all of the copies stuff progress etc. should go to the transfer maybe in a collection keeping track of uploads and progress - we should slim down the filerecord so that it contains as little info as possible - mainly static data. The transfer knows when the file is uploaded and contacts the FS.Collection saying that the file is uploaded and ready to be transported in to storage adapter. The FS.Collection will use the file worker is available if not it will store the file directly to the one allowed storage adapter - it would be nice to be able to throttle this via a task manager. If file worker available we allow the beforeSave behaviour. Again repeating this pr. storage adapter is really not that big a deal - its basically just the next task in the queue manager. I dont personally see a problem with multiple stores pr. file - it seems to work pretty good? Doing this at runtime eg. The original thought / reason for multiple stores/copies (org. called filehandlers) where |
Just to be clear, I'm fine with concept of a file in a collection having multiple stores, I think that's a good idea that should be kept. My issue was that those stores should always and only have the same exact data in them. So if something like beforeSave is run, it should run against the first store, and then subsequent stores are exact copies of that. |
This is where the idea of having a collectionFS level onChange function comes in. If you want every uploaded image to have an associated thumbnail generated, you write an onChange handler for the image collection that has the logic to detect changes to full size images and keeps their linked thumbnails up to date. The metadata required and where/how the thumbnails are stored is an implementation detail. |
Having just re-read the above two comments, I reminded myself that once you have onChange, beforeSave becomes redundant and more confusing since you can have multiple stores on a file, but only the first one can meaningfully have a beforeSave. Basically, in my reimagining of this beforeSave goes away and is replaced by much more flexible onChange logic on the collectionFS. |
Adding just a bit more... So onChange is directly analogous to supplying |
Just trying to follow and figure out the problem you want to solve I'm not there yet, So as I understand it we are talking about two concepts:
So thats really to very different tasks - I guess, we currently dont support 2. Or is it out of principle that every version should be a document with an id? The prior version of the storage adapters did have their own "filerecord" it had The nice thing about having multiple versions / stores pr. file is reference - eg. if browser only supports the
I did make a small overview of the cfs project yesterday, its rough wip overview of the architecture and what we are refactoring at the moment: https://www.dropbox.com/s/arlq4ed3r1gh5ty/overview.pdf Both Eric and I was a bit surprised to see it - why should file upload be so complicated? Well, we are actually talking about creating a few more packages, I think we are lucky to have the Meteor package system. |
@vsivsi, I understand what you're saying. FileWorker would:
Some comments:
|
Ok, well in a way it is one file typically - an image/sound/video just in different formats - the content is "the same".
Its all words we tend to use about the same thing - maybe we should think about these and what patterns and problems they imply? Eg.:
Maybe stores isnt the best term? Linking copies and have them update triggered by onChange events not too sure about that - seems more complicated? |
I'll sleep on it |
Good idea. Maybe we should all sleep on it a bit and have a hangout debate next week sometime. :) |
yep! |
If you follow this abstraction, you are designing a Content Management System, not a File System, because the "things" you are calling "the same" (e.g. different encodings of a single TV show episode) aren't represented by the same bits. I totally agree that "content" can be a "thing"; just don't call that "thing" a "file", because This concept is so well-settled that 99+% of developers who encounter CollectionFS will not intuitively understand that a single "file" in your system can return different data depending on how they ask for it. The solution to the problem @raix articulates (managing content that is "the same") is to build a CMS on top of CollectionFS that implements a clean set of "content" abstractions. I'm not a pedantic person, and so I see how it may appear like I'm flogging a purely philosophical point here, but libraries/packages are made/broken by how "cleanly" they define a useful abstraction and implement it in a simple/accessible way. IMO, this is the single biggest differentiator of "well-" and "badly-" designed software. "Files" have proven to be one of the most useful and durable abstractions in all of computer science for decades, so why mess with it? |
Here's how I see Stores fitting into the system. I think there should be an allowance for multiple stores for a file. However, I see this as a "nice to have" feature, but not "must have". @aldeed was correct, the multiple stores may serve to back each other up, they may also allow for things like load balancing in the future. I fully agree that stores should be black boxes, the only rule should be that the bits you put in are the same bits you get back out later, regardless of which store you request them from. What a store does on the inside (e.g. compression, encryption, replication) should be irrelevant. |
@vsivsi, I think we're basically building a file system layer, a content (file) management system, and file uploaders all in one ecosystem, but in discrete packages that can be mix and matched. Given that this is the case, we should make sure that it makes sense in any context. |
I think if we use CMS as a description it would be misleading, it's more of a FMS. Why do we need multiple stores? Today we have things like dropbox, google drive etc. They sync, we might want to be able to connect with these - a common task is resizing images and converting file formats it's really a small footprint on the server and a Big help - a filesystem for the Web now days are not to be compared with 50 year old specs. It's sort of the transport method that sets some of the file api, it's simple to use, I dont think devs will have a problem understanding the concepts and what to expect. Beforesave is just a small part of the tools, we could extract and build upon cfs but it would not be well designed - that Said it's possible to create a replacement package for the cfs-worker altering that behaviour - we created this system of alot of small packages that can be stacked and reused by others. Personally i started this project because i was tired by the way files are normally handled in asp, php, jsp, .net etc. Not much have changed that area the last 24 years i've been programming. Uploading a file in cfs should not be harder than declaring the collections and use the ui components. But i still have dificulties in understanding the org. problem that you wanted to solve. Devs dont have to use multiple stores, if only using one store it would work 1:1. Please checkout the overview it make more sense than my ipad typed text :) |
@aldeed That's a great way of looking at it. In that framework, my argument boils down to: CollectionFS --> FileFS --> SA all deal with files (in the traditional sense). They faithfully carry metadata and have appropriately scoped execution hooks added to enable higher level abstractions to be built up in higher layers. My notion of CollectionFS having
For
There may also be
|
It's not the store that should resize, we are in refactoring - it's the file worker that should be able to exec. So basically the beforesave is part of the worker package (even is it's an option we set in the sa) |
@raix That's fine, it's where it's "attached" that I was referring to. Also, shouldn't you be asleep by now? I'm going to stop now because I need to drink beer with my friends! 🍻 |
Transform instead of beforesave makes sense, |
Hehe yep should be sleeping, normally it's me poking Eric to get out of my timezone when his up late :) but we have set a deadline before april and it's a fun project, hard to let go sometimes. Well see you on the flipside, enjoy the beer! |
@aldeed just read the message above mine, agree, you say in 3 Lines what i say in 30 Lines (glad it's not js) Agree it's kind of a file managing system FMS. |
@aldeed @raix Hey guys, what's the current status of everything that's committed? I'm trying to test out my changes to "unwrap" the MongoDB calls in cfs-gridfs, but no data gets written to any SAs any more, and I'm not seeing any errors in any consoles. Did some bit of interface change overnight that I haven't picked up and I'm getting silent failures? As a general aside, the structure and inter-dependencies among the sub-parts of this project are getting really complicated. I'm all for modularization but the current state of the |
A bit more information about above "no data written to SAs" problem. |
I'm going to do some integration testing right now, so I'll see what's wrong. There are actually no circular dependencies. The smart.json sometimes includes packages that are circular because they are dependencies for running the tests, but they are not dependencies for running the actual package, so they won't be used. |
@aldeed have been working on storage adapters, it wip. |
@vsivsi, I'm not seeing any problems with SAs get, put, or del, but there is an issue with uploads not working right now. Will work to fix that. You can test by inserting a file on the server in the meantime. I did make a small change to the gridfs SA. |
Yes, I saw all of that. There's currently a branch on cfs-gridfs (remove_wrap_async) with the _wrapAsyncs all removed if you want to test with that... :-) |
OK, my latest round of pushes should have client inserts and uploading working again. @vsivsi, let me know if you're still having troubles. @raix, while I was in cfs-tempstore, I also pulled temporary chunk tracking out of the file object and into a separate collection. We still need to look at how we're dealing with file updating, figure out the correct way, and make sure our code is correct. Right now, a PUT (update) simply adds the received chunk to the tempstore for the designated file. This works within our system, but doesn't allow for changing the file's metadata, like content type. I'm not sure if we want to allow that, or if one should instead remove and re-insert a file. We should really take another look at resumablejs. Now that we're shifting to HTTP uploads as the default, maybe it would make sense to use resumablejs as our client-side uploader? In other words, |
Im ok with resumablejs - does work with direct s3 upload? (just curious) |
@aldeed Upload to cfs-gridfs seem to be working again. Is it using HTTP PUT for upload now? The thing that still seems broken is HTTP GET in the browser. I'm getting 503s, which I'm guessing is because the X-Auth-Token header isn't being set by the browser when I use |
Actually the above GET problem is timing related. If I reload the page then the GET works (or when the page redraws for any reason). So it seems like the HTTP access point returns 503 for a short period between the upload and storage in the SA and the reactivity in the |
@vsivsi, for me, the As far as the interim period, this is something we've discussed a bit. I think a good solution would be to add an <img src="{{url store='thumbs' alt='spinner.gif'}}"> We could also handle through server-side redirect responses, but it seems rare that you would want to blindly redirect everything to the same resource. One can also handle using @raix, I haven't looked into resumable much yet. Don't know if it supports S3 upload as it seems to use custom params, but maybe the param names are customizable. It also uses multi-part posts. Not sure if PUT is supported. Will need to explore more, maybe later this week.
Good idea!
Yep! |
Also, I'm on the |
Oh, I haven't tested with |
It might be, but I'm just using |
Oh, hmm, actually if you're getting 503, then that means they've already reactively updated after storage is done. Prior to storage, |
Just tested, it fails the same way when logged out / unsecured, so definitely not token related. Here's what I see on the browser side:
|
OK, still working fine for me, even with token. Can you provide a minimal repo for me to clone and test with? I don't know if I forgot to push some code or what. |
Are you using the latest shark meteor/meteor@9b2b612? |
Maybe not the latest. Let me make sure. |
OK, still no issues on the latest {{#each fsFile}}
{{#unless cfsIsUploading}}
{{#with url store='thumbs'}}
<div><a href="{{../url}}" target="_blank"><img src="{{this}}" alt="" class="thumbnail" /></a></div>
{{/with}}
{{/unless}}
{{/each}} |
I'm working on isolating just this piece from the rest of my app. We'll see what happens then... |
Here you go. I'm just using |
Your test app is much prettier than mine! I'm able to replicate. Still haven't figured out what's different from mine. Maybe I have another helper that's reacting and masking the issue. I'll have to figure it out tomorrow. |
Bootstrap makes everything pretty. Sent from Vaughn's iPad
|
OK, this was my bad. For some reason I made some changes to the |
Great, I'll check it out this afternoon. |
Finally got around to testing the newest and everything looks good. One case that still doesn't react is when the user logs in or out. Since |
fixed user deps in auth url |
I noticed that, too. Thanks, @raix! |
Did we solve this guys? |
I think this thread got a bit derailed on another issue, but as far as the original post in this issue, I am personally still thinking about it. Sometimes I think it would be a good pattern, but most of the time I think it would be a big re-org and we wouldn't necessarily get much out of it. One thought I had: We could potentially implement this side-by-side, allowing either multiple stores or more of an |
ok, I have to read this issue one more time when ready, btw. the node js event emitter could perhaps used for event handling. |
Based on a suggestion from @vsivsi.
This could be a good idea, but there is a lot to consider, so here's my attempt at figuring out how the new architecture might work and what the possible issues might be.
Generally speaking,
stores
option would becomestore
and copy-making would become the job of another optional packageuploader
option is not null,FS.Collection.prototype.insert
then passes the insertedFS.File
instance to the uploader function specified (which is the one from thecfs-upload-http
package by default, but could also be DDP or one provided by s3 cloud pkg). I already added thisuploader
option the other day.beforeSave
. (Currently we put this info intocopies
property, butcopies
would no longer be necessary.)insert
on. Maybe some kind of API that lets you define a collection relationship map?copies
property in aFS.File
to give us easy access to retrieving a certain related copy, but we would lose that.copies
should be changed to an array ofFS.File
s containing pointers to related files in related collections?The text was updated successfully, but these errors were encountered: