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

Refactor to no longer be a GenServer #3

Closed
jeffweiss opened this issue Apr 6, 2016 · 4 comments
Closed

Refactor to no longer be a GenServer #3

jeffweiss opened this issue Apr 6, 2016 · 4 comments
Assignees

Comments

@jeffweiss
Copy link
Owner

Running everything thing through a GenServer has two primary problems:

  1. All requests serialized through single process
  2. Long API calls can cause the GenServer calls to time out
@eldritchideen
Copy link
Contributor

Today I was getting a lot of timeouts due to the response from SalesForce taking longer than the 5s the GenServer.call waits to hear back.

@jeffweiss
Copy link
Owner Author

@eldritchideen it's still a bit raw, but master has a new Forcex.query/2 that might be useful. It requires manual pagination right now, but the timeout issues should been eliminated. I've updated the README, but the flow should go something like this:

Configure Forcex, either through mix config or environment variables

config :forcex, Forcex.Client,
  username: "[email protected]",
  password: "my_super_secret_password",
  security_token: "EMAILED_FROM_SALESFORCE",
  client_id: "CONNECTED_APP_OAUTH_CLIENT_ID",
  client_secret: "CONNECTED_APP_OAUTH_CLIENT_SECRET"

config :forcex, :request_options,
  recv_timeout: :infinity

Then you'll want to create a Forcex.Client. This client struct can be shared amongst many processes hitting the SFDC API simultaneously.

ASIDE: Be forewarned, however, that SalesForce has a hard limit of 10 concurrent queries per user and the insidious part is that new queries aren't rejected, but the API silently invalidates earlier queries in a FIFO manner, regardless of if they're still in use (ask me how I know :-/).

Forcex.query/2 provides enough info to manually page through the results, but it's certainly nothing as elegant as the streaming I'll implement as part of #4. The current, ugly pagination currently looks something like this:

client = Forcex.Client.login |> Forcex.Client.locate_services

first_page = Forcex.query("select Id, Name, Company, Email from Lead order by CreatedDate desc", client)
second_page = first_page |> Map.get("nextRecordsUrl") |> Forcex.get(client)

As you may have guessed from the above config, I've also enabled configuring specific options, as defined by HTTPoison.request/5. So you should be able to wait for an "infinite" amount of time for SFDC to return with your query results.

I'm going to keep working on this over the next couple days. If you have an opportunity to try out master, please let me know what you think.

@eldritchideen
Copy link
Contributor

Thanks, I'll take a look when I can.

@jeffweiss
Copy link
Owner Author

@eldritchideen I just pushed 0.3.0 to Hex. In addition to the usage mentioned earlier in this issue, v0.3.0 will, at compile time, generate modules for each Force.com object your user can access.

client = Forcex.Client.login |> Forcex.Client.locate_services

first_page = Forcex.query("select Id, Name, Company, Email from Lead order by CreatedDate desc", client)
second_page = first_page |> Map.get("nextRecordsUrl") |> Forcex.get(client)

contact = Forcex.SObject.Contact.get("003G000001iyRm9", client)

obj = Forcex.SObject.MyCustomObject__c.get("099G000001abCd9", client)

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

No branches or pull requests

2 participants