My read was the same as yours: AdWordsServices doesn't retain the session. We have thousands of accounts so I don't want to have one per account if it's a "heavyweight" object as indicated in the migration guide. So that's why I came up with idea of a wrapper object that will ensure thread safety.
But I think this back-and-forth you and I are having is indicative of the need for some additional examples or documentation of best practices, so that each person doesn't have to puzzle it out and invent a solution. On Wednesday, October 10, 2012 7:30:13 AM UTC-4, Oliver wrote: > > I need to correct myself. AdwordsServices itself does not hold a > reference to the session. It's the actual service objects generated from > AdwordsServices that do. e.g. > > CampaignServiceInterface campaignService = adWordsServices.get(session, > CampaignServiceInterface.class); > > > But AdwordsServices is not thread safe, so caching it at the account level > instead of the appliaction (multiple accounts) level will make things > easier. > > Oliver > > > On Wednesday, October 10, 2012 11:35:54 AM UTC+1, Oliver wrote: >> >> Here is what I think: >> >> The AdwordsServices object holds a reference to the AdwordsSession >> object. Since AdwordsSession is linked to one account ID only, you need to >> be very careful not to use AdwordsServices across accounts without >> switching the session. >> >> What we do is create and cache a copy of AdwordsServices and >> AdwordsSession for each account. The objects are re-used for all calls on >> an account. We're careful not to use multithreads when accessing the >> Service API for an account (AdwordsServices). Using multi-threads when >> downloading reports is fine. >> >> Refreshtoken: my understanding is that the client libraries will take >> care of automatically refreshing the OAuth2 token if needed (however, I >> have not tested this yet). So, in theory, all you need to do is persist >> the refresh token and keep using it until the end user revokes access. >> >> If anyone has better ideas than the above please let us know. >> >> Oliver >> >> >> >> Tuesday, October 9, 2012 7:28:45 PM UTC+1, j.e.frank wrote: >>> >>> I had seen that post, which is what prompted me to post my own. I am >>> trying to better understand how multiple threads should/can share objects. >>> I don't want to go the route of "each call creates its own set of >>> objects", if there's a more efficient way to do things. >>> >>> As an example, consider the AdWordsServices class, which is new (to me). >>> The migration guide says "The AdWordsServices object is fairly >>> heavyweight and should be instantiated once and reused as much as >>> possible." It is not thread-safe, but it doesn't retain any state. My >>> conclusion is that if I make a singleton AdWordsServices object for use >>> throughout my code, as long as I make sure no two threads are calling >>> adWordsServices.get at the same time, that should be more efficient than >>> creating a new one every time I need to make an AdWords API call. In order >>> to achieve thread safety, I will probably wrap the AdWordsServices object >>> inside my own singleton object, with a synchronized "get" method that >>> passes through to the wrapped AdWordsServices object. That's an example of >>> a best practice that I'm looking for. >>> >>> As for the OAuth2 credential, I have managed to create a valid one from >>> a saved refresh token, by building the credential and then calling >>> credential.refreshToken(). I'm still trying to figure out whether I need >>> to do this refresh step or if it would happen automatically, and also >>> whether calling refreshToken() is going to invalidate any AdWordsSession(s) >>> that are currently using the credential before it got refreshed. I'm going >>> to write some tests, and once I understand the credentials, tokens, and >>> AdWordsSessions better, I will be able to come up with a coding strategy >>> that fits my use case (long-lived services, all with the "same" login). >>> But if there are examples already that match my use case, it will be a big >>> time-saver and also make it more likely that I don't misunderstand how >>> things work, or come up with a flawed solution. >>> >>> On Tuesday, October 9, 2012 1:42:49 PM UTC-4, Oliver wrote: >>>> >>>> You will need to persist the refresh token and account ID so your >>>> services can resume on their own in case of a restart. You can ceate >>>> valid >>>> AdwordsSession and AdwordsServices on the fly if you have these two fields. >>>> >>>> Also, this might be of help: >>>> >>>> https://groups.google.com/forum/?fromgroups=#!topic/adwords-api/zf0slvrjkMs >>>> >>>> Oliver >>>> >>>> On Tuesday, October 9, 2012 5:08:03 PM UTC+1, j.e.frank wrote: >>>>> >>>>> I am trying to migrate to v201209 from v201109. I have several >>>>> long-lived services that use the AdWords API on behalf of my MCC account, >>>>> for example to run reports, to get ad details, and so forth. I'm trying >>>>> to >>>>> understand how I should be using the new session/service objects, such >>>>> that >>>>> more than one thing can be happening at once, but that I don't create a >>>>> new >>>>> session or service object when I don't need to, and also that I use my >>>>> OAuth2 tokens appropriately (refresh if necessary but not every time I >>>>> need >>>>> to make a call). I've seen several pieces of example code, but they are >>>>> self-contained so they always get a new session, new service object, >>>>> refresh the OAuth token, etc. Are there any examples more suitable for >>>>> long-running services that will be invoked from time to time? >>>> >>>> -- =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ Also find us on our blog and discussion group: http://adwordsapi.blogspot.com http://groups.google.com/group/adwords-api =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ You received this message because you are subscribed to the Google Groups "AdWords API Forum" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/adwords-api?hl=en
