That's not quite what I had in mind, because I have a lot of accounts to deal with and I don't want to create all the service objects ahead of time. I am planning to have one AdWordsServices object, wrapped to ensure thread safety. I will create the service objects on demand using this object, and throw them away after the call(s) complete. I'm still working on how I plan to use the OAuth2 credential(s) to create AdWordsSessions. Since I have so many accounts, I don't want to have a cache of sessions or anything per account, although I could create a "session pool" if it turns out to be expensive to make AdWordsSessions.
On Wednesday, October 10, 2012 3:29:53 PM UTC-4, Oliver wrote: > > Agreed. Best practices would be of great help. > > I guess your solution of a 'singleton' AdwordsServices would work. Is the > following what you had in mind: > > - The only time we need AdwordsServices is to create the service objects. > The service objects can be created at any time during the long lived > process. > - We create only one global copy of the AdwordsServices object. > - The first time access to an account is needed, we use the global > AdwordsServices (in a thread safe way) to create all the service objects we > will need for the whole duration of the process. > - We cache the service objects instead of AdwordsServices at the account > level, and hence no need to use AdwordsServices again. > > Oliver > > > On Wednesday, October 10, 2012 5:00:38 PM UTC+1, j.e.frank wrote: >> >> 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
