Realm Serverless Parameter Upload / External HTTP POST Limits?

I went through some of the videos and articles done by Lauren Schaefer and Drew DiPalma about what could be done with Realm Serverless, and decided to see if I could run before I start walking. So I decided to write a Realm Serverless Function that could handle image uploads from our mobile client and post them into our Cloudinary account as an example.

Basically in the client we create a Data URI from the image and we found out that there are limits to the BSON Parameters that we could send. It seems that limit is around 10KB. So once that was determined, we chunked the fileData argument into a BSONArray of BSON strings.

The code works fine with almost any image size if I run it in Node.js (Nice trick using the module.exports = exports from Lauren’s video), and it does work in the Realm Serverless if the image is small (I’ve tried 13KB, not sure that’s the limit), and it seems to not work on images that are around 300KB. It seems that it’s timing out on my axios request. (I imported crypto, and axios as node_modules into my Realm Application). As the console.log shows that it makes it to that request. (… ‘About to upload to: ’)

Disclaimer: I’m actually not looking for the response of that you shouldn’t use Realm Serverless Functions for this, (we’re willing to concede this already.), however it would be better to know what the limits are so we can determine what kind of use cases make sense for Realm Serverless Functions.

What could be the reason for the timeout as the normal 13KB request takes about < 5 seconds?

Realm Serverless Source

iOS Source

3 Likes

Hey Bain,

Does the console show anything after the timeout (e.g. execution time limit exceeded.) when you use the larger image? We do have a 90s execution limit on functions - see here, and it sounds like the large image may be causing that axios request to be longer.

It could also be something to dig in with axios - we have a context.http module and I’m curious if you’re seeing the same behavior with that as well.

2 Likes

@Sumedha_Mehta1 It does. I’m a little surprised that it takes as long as it does. If I run it on my local machine (I know it’s a cliche), with just node itself, the total time is ~ 2-3 seconds for the big file. It also seems to get to the axios call fairly quickly. I don’t mind switching over to the context http, to show it happening, however I just imported axios because the hashing function of the utils.crypto wasn’t working for me, so I imported axios & crypto together. I’ll see if I can turn it around quickly and report back.

Actually let me clarify that (might help anyone that’s an SDK developer), I only receive ‘execution time limit exceeded’ if I run it from the functions console. If I run it from my iOS app it seems to time out after 60 seconds or so (which might be the RealmSwift SDK not using the same timeout as the function.) If I check the logs, it says ‘operation canceled’. Which makes me think the client cancelled the operation.

1 Like

@Sumedha_Mehta1 that worked, and is a lot more performant.

(For reference or for future travelers) I switched the axios request to the following: (importing https at the top of the function):

  return new Promise((resolve, reject) => {
    const req = https.request(options, response => {
      let responseData = '';
      console.log('cloudinary status code:', response.statusCode);
      console.log('cloudinary headers: ', response.headers);
      
      response.on('data', (chunk) => {
         responseData += chunk;
      });
      
      response.on('end', () => {
        console.log(`Completed Upload Response.`);
        const jsonData = JSON.parse(responseData);
        
        const { asset_id, created_at, format, overwritten, secure_url, url, version } = jsonData;

        console.log(`AssetID: ${asset_id}`);
        console.log(`Created At: ${created_at}`);
        console.log(`format: ${format}`);
        console.log(`secure_url: ${secure_url}`);
        console.log(`url: ${url}`);
        console.log(`version: ${version}`);
        console.log(`overwritten: ${overwritten}`);
        
        resolve(jsonData);
      });
    });
    
    req.on('error', error => {
      console.log(`Received an error when uploading:`, error);
      reject(error);
    });
    
    req.write(formData);
    req.end();  
  });
2 Likes

I’m so glad you found my videos useful! :smiling_face_with_three_hearts:

3 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.