Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAsyncWrapper available on Mac #371

Closed
barnabygordon opened this issue Nov 8, 2018 · 2 comments
Closed

WebAsyncWrapper available on Mac #371

barnabygordon opened this issue Nov 8, 2018 · 2 comments

Comments

@barnabygordon
Copy link

I'm trying to execute a large number of http requests across many cells using the same function but anything more than 10 function calls is just too slow.

I'm hoping that the WebAsyncWrapper can help me out (from what I've read here #352) but I need my module to run on Mac's as well as Windows systems.

Is any work being done (or can be done) to adapt the WebAsyncWrapper for use on Mac?

@timhall
Copy link
Member

timhall commented Nov 8, 2018

@barnabygordon I've looked really hard at possible options for this and there are some possibilities for adding async support on Mac, but they are all very difficult / may not work. It should be simple to allow Excel / OS a chance to do some work with DoEvents (I'll look into adding this), but processing requests in parallel is difficult. popen for libc on Mac runs cURL asynchronously, but it is synced in VBA by reading from the file (used in ExecuteInShell). If I could open / schedule an event loop to perform these reads it would be async, but I haven't found a good way to do that. Another option would be to defer it so that it runs at a slightly later time (ideally 1ms) so that all the requests can be started at the same time. OnTime seems like a good way to do this, but it only has 1 second resolution, so any async request would take at least a second to resolve.

Another thing to note is that if you are making a web request as part of a worksheet function (e.g. =STOCKVALUE(A1)) then this can't be async since Excel does some low-level work to prevent accessing the cell after the worksheet function has run (at least I've tried and can't find a way, maybe you could with a ton of stored state)

I would try adding a DoEvents before the end of the loop here and see if that speeds it up somewhat. (If it does, please let me know and I'll make the change to WebHelpers)

VBA-Web/src/WebHelpers.bas

Lines 1638 to 1645 in ee6f34d

Do While web_feof(web_File) = 0
web_Chunk = VBA.Space$(50)
web_Read = CLng(web_fread(web_Chunk, 1, Len(web_Chunk) - 1, web_File))
If web_Read > 0 Then
web_Chunk = VBA.Left$(web_Chunk, web_Read)
ExecuteInShell.Output = ExecuteInShell.Output & web_Chunk
End If
Loop

@barnabygordon
Copy link
Author

@timhall thank you for the rapid response! I just tried modifying ExecuteInShell by adding a DoEvents but it doesn't seem to be affecting the speed at all unfortunately.

I am executing my function as part of a worksheet (e.g. =STOCKVALUE(A1)) and then copying this across multiple cells (>100). This is probably out of the scope of VBA-Web, but could a the solution to this issue might be to somehow intercept the function calls as they are made in order to group them?

The api that I'm using can accept an array or arguments and return multiple values, so a more efficient way to approach this may be to execute a single http request and then distribute the response amongst each of the cells. Do you know if this is at all possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants