Skip to content
This repository has been archived by the owner. It is now read-only.

Adding files from server Collection FS. #362

Closed
inderpreetsingh opened this issue Jul 13, 2014 · 4 comments

Comments

@inderpreetsingh
Copy link

commented Jul 13, 2014

I am making an app that shows 3d models online. I make users upload a ".g file", .g files cannot be directly viewed so they have to be converted into ".obj files". It should be noted that a single ".g" file gets converted into multiple obj files and I want to feed those newly created obj files to my three.js model viewer.

The logic that I am trying to accomplish (suggested by Jonas Aschenbrenner in mailing list) is:

  1. Use transformWrite to create the converted files.
  2. Start the convertion in the transformWrite handler.
  3. Create a new FS.File for each .obj that is generated.

I have been able to accomplish first two steps but I am stuck on third. Whenever I create a new FS.File Object in callback to child_process that runs the shell commands necessary for conversion, I get this error

Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

What am I doing wrong ?

I have tried to put the code that creates new FS.File object in Meteor.bindEnvironement but that didn't help. I also tried wrapping the child_process.exec in Meteor.bindEnvironment but got nothing.

@aldeed

This comment has been minimized.

Copy link
Member

commented Jul 13, 2014

I'm not entirely sure where the bindEnvironment is missing without seeing some code, but I think there could be a more robust way to do what you need to do.

  1. Store in two separate collections with two separate stores.
  2. For the .g store, add a "stored" listener in server code: gStore.on("stored", listener).
  3. In the listener, get the data for the .g file and convert it to .obj files, storing them in objCollection/objStore.
  4. Use some sort of reactive flag your viewer can watch to know when all related obj files have been created and stored.

I suggest this because transformWrite is supposed to be for passthrough transformations on the same data stream, but I'm assuming that your transformation is not implemented as a passthrough stream, and also the one-to-many aspect is more prone to error, so it's best if you've safely stored the source file so that you can implement retries.

@aldeed aldeed added the question label Jul 13, 2014

@inderpreetsingh

This comment has been minimized.

Copy link
Author

commented Jul 14, 2014

My collections file contain https://gist.github.com/inderpreetsingh/03ba37d72ef2430faecf
and here's the server method that converts files https://gist.github.com/inderpreetsingh/cce7c0fa6fac36787aab
Where is my bindEnvironment missing ?

Also, I was unable to add the stored listener, can you point me to some example ?

@aldeed

This comment has been minimized.

Copy link
Member

commented Jul 14, 2014

In your server method code, the callback to exec needs to be wrapped because it's a non-Meteor function. Usually I think you don't need it if you're not calling Meteor code within the callback, which it seems like you are not doing, but I don't have a full understanding, so I would try wrapping one or both of your exec callbacks and see if that fixes the error. Just put the function within Meteor.bindEnvironment(func).

For the listener approach, I would think this should work:

Give your store a variable in collections.js:

modelFilesStore = new FS.Store.FileSystem("modelFiles", etc...

Then attach the listener:

modelFilesStore.on("stored", function (fileObj) {
  console.log("transform writing");
                var fileId = fileObj._id;
                Meteor.call('convertFile', fileId, function(err) {
                    if (err) {
                        console.log("convertFileError");
                        console.log(err);
                    } else {
                        console.log("inserted");
                    }
                });
});
@inderpreetsingh

This comment has been minimized.

Copy link
Author

commented Jul 15, 2014

Thanks a lot aldeed, I was adding Meteor.BindEnvironment on the whole exec function rather than just callback. After wrapping the callback, the conversion and insertion into collections worked like charm. :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants
You can’t perform that action at this time.