Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. If it fails, try again

If it fails, try again

Scheduled Pinned Locked Moved The Weird and The Wonderful
database
37 Posts 19 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Sander RosselS Sander Rossel

    Customers do that :laugh: I have a similar story with a printer. The user pressed the print button to print somewhere around 100 to 150 invoices. It often happened that the printing stopped after 50 or so invoices. And always at the end of the day (because that's when they printed invoices). So I was testing my software, looking for bugs, writing "fixes" for "what could be it", added additional logging, everything, but I was never able to find the problem. And when I visited it didn't happen, of course. This went on for weeks. Then my manager visited them, for completely unrelated business, and called me "Is that print problem fixed already? I'm about to leave, but they're going to print invoices so I can check on them now." He checked and you'll never believe what their issue was. They clicked the print button and SHUT DOWN THEIR COMPUTER TO GO HOME!!! :wtf: :omg: :~ X| Never did it occur to them that shutting down the computer would stop it from printing. I can tell you I felt like driving a truck over their computers! :laugh:

    Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

    D Offline
    D Offline
    Daniel Wilianto
    wrote on last edited by
    #19

    True story. Some users seems to assume that printers have internal memory which would keep our queued documents. This assumption comes from a fact that printer keeps printing even when they closed our software. They don't know that these queued documents are stored on operating system's printer spooler service. Some colleagues once asked me, why did her printer stop printing? I who was in the middle of serious work mode, glanced over at her desk and yelled, you turned off your computer, that's why!

    R 1 Reply Last reply
    0
    • G gjp1311

      Beacause it will surely work a 100% the second time :-\

      SqlCommand cmd = new SqlCommand(query,conn);
      SqlDataReader reader = null;
      try
      {
      reader = cmd.ExecuteReader();
      }
      catch(InvalidOperationException e)
      {
      cmd = new SqlCommand(query,conn);
      reader = cmd.ExecuteReader();
      }

      K Offline
      K Offline
      kalberts
      wrote on last edited by
      #20

      If "try again!" always was silly coding practice, the the concept of "busy waiting" would not be known. Busy waiting does have its place, especially in embedded systems where the processor has nothing else to do. Another situation is where several activities are competing for the same resource, but they hold the resource comparatively briefly. As long as you can modify all the competitors, you could program the queueing mechanism, where a process trying to access a busy resource is sent to sleep in a queue and woken up when it gets its turn. Often you can only modify some of the competitors. The effort of implementing a queue mechanism may be high. If the risk of collision is small, it simply doesn't pay. I have fairly recently programmed a couple "try again" cases: On a quite heavily loaded file system, the number of exceptions due to confliciting accesses was higher than desired. So, when making modifications to a set of files, I make one try for each. Those failing are put into a list for retrying, and a second attempt is made once the first round was completed. Only after a second try, the user is notified. We went from too many access collisions to almost none. Sometimes, the second try came too fast, and the file was still busy. So I added a 5 ms sleep before starting a second round, and after that I haven't seen a single collision. This "try again" code is next to trivial, and it does solve a real problem. So I cannot agree that the strategy is silly in every case. Sometimes it makes perfect sense.

      K R 2 Replies Last reply
      0
      • Sander RosselS Sander Rossel

        We actually had such a rule. Our automated build system would keep giving us errors "At least 25% of a file must be comments." X| After some insistence from my part they disabled that rule :D

        Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

        K Offline
        K Offline
        kalberts
        wrote on last edited by
        #21

        I don't like the way it is phrased. If you phrase it: "At least 25% of the lines should be explained by a comment", then I agree. Leaving more than 75% as "self explanatory" is very costly, five years later. I am very fond of end-of-line comments; they can be made short, to the point, and at the right place. If you need something between the software architecture documentation (I often describe "software architecture" as "the structures that will remain the same if you reimplement the system in a different programming language"), a comment block may apply to, say, an entire function, or at least the core part of it. From the moment you compile a source file for the first time and three weeks thereafter, any code is "self explanatory". After two years, not even the code written by yourself qualifies. A classic: Geek & Poke[^]

        Sander RosselS 1 Reply Last reply
        0
        • G gjp1311

          Beacause it will surely work a 100% the second time :-\

          SqlCommand cmd = new SqlCommand(query,conn);
          SqlDataReader reader = null;
          try
          {
          reader = cmd.ExecuteReader();
          }
          catch(InvalidOperationException e)
          {
          cmd = new SqlCommand(query,conn);
          reader = cmd.ExecuteReader();
          }

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #22

          Sometimes it will - for example, the SqlConnection class was updated recently to retry a failed connection, to account for unreliable networks. However, an automatic retry can still have unintended consequences: Try and try again: not always a good idea (at least not for SSMS!) | SQL Server Customer Advisory Team[^]


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          1 Reply Last reply
          0
          • K kalberts

            If "try again!" always was silly coding practice, the the concept of "busy waiting" would not be known. Busy waiting does have its place, especially in embedded systems where the processor has nothing else to do. Another situation is where several activities are competing for the same resource, but they hold the resource comparatively briefly. As long as you can modify all the competitors, you could program the queueing mechanism, where a process trying to access a busy resource is sent to sleep in a queue and woken up when it gets its turn. Often you can only modify some of the competitors. The effort of implementing a queue mechanism may be high. If the risk of collision is small, it simply doesn't pay. I have fairly recently programmed a couple "try again" cases: On a quite heavily loaded file system, the number of exceptions due to confliciting accesses was higher than desired. So, when making modifications to a set of files, I make one try for each. Those failing are put into a list for retrying, and a second attempt is made once the first round was completed. Only after a second try, the user is notified. We went from too many access collisions to almost none. Sometimes, the second try came too fast, and the file was still busy. So I added a 5 ms sleep before starting a second round, and after that I haven't seen a single collision. This "try again" code is next to trivial, and it does solve a real problem. So I cannot agree that the strategy is silly in every case. Sometimes it makes perfect sense.

            K Offline
            K Offline
            kmoorevs
            wrote on last edited by
            #23

            Member 7989122 wrote:

            So I cannot agree that the strategy is silly in every case. Sometimes it makes perfect sense.

            :thumbsup: Great examples but not quite the same as the OP where it doesn't make sense to try the same command again right away. This also brought to mind a program I have to migrate database objects...those having a dependency yet to be created fail and get put into a recursive 'try again' queue. :)

            "Go forth into the source" - Neal Morse

            1 Reply Last reply
            0
            • K kalberts

              I don't like the way it is phrased. If you phrase it: "At least 25% of the lines should be explained by a comment", then I agree. Leaving more than 75% as "self explanatory" is very costly, five years later. I am very fond of end-of-line comments; they can be made short, to the point, and at the right place. If you need something between the software architecture documentation (I often describe "software architecture" as "the structures that will remain the same if you reimplement the system in a different programming language"), a comment block may apply to, say, an entire function, or at least the core part of it. From the moment you compile a source file for the first time and three weeks thereafter, any code is "self explanatory". After two years, not even the code written by yourself qualifies. A classic: Geek & Poke[^]

              Sander RosselS Offline
              Sander RosselS Offline
              Sander Rossel
              wrote on last edited by
              #24

              Depends, most of the code is just properties, setting, getting, some database queries, standard stuff. I always get a little sad when I see comments like:

              // Assign the variable.
              someVar = someVal;

              // Loop through the products.
              foreach (Product p in products)

              // Save the customer.
              customer.Save();

              // Save the customer. [notice the error]
              product.Save();

              Unfortunately, I've only seen comments like that. And because of these kind of comments I came to detest them. You may think I'm overreacting, but those are actual real-life comments I see almost daily. I have 7 years of experience and I have yet to find a single comment that is actually helpful. I rarely comment my code, maybe once or twice when there were some weird side-effects (which is just bad code). I'm at the point that I prefer my code uncommented (especially when it's bad code, people who write bad code also write bad comments). Yeah, comments can't be done right.

              Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

              N 1 Reply Last reply
              0
              • Sander RosselS Sander Rossel

                Depends, most of the code is just properties, setting, getting, some database queries, standard stuff. I always get a little sad when I see comments like:

                // Assign the variable.
                someVar = someVal;

                // Loop through the products.
                foreach (Product p in products)

                // Save the customer.
                customer.Save();

                // Save the customer. [notice the error]
                product.Save();

                Unfortunately, I've only seen comments like that. And because of these kind of comments I came to detest them. You may think I'm overreacting, but those are actual real-life comments I see almost daily. I have 7 years of experience and I have yet to find a single comment that is actually helpful. I rarely comment my code, maybe once or twice when there were some weird side-effects (which is just bad code). I'm at the point that I prefer my code uncommented (especially when it's bad code, people who write bad code also write bad comments). Yeah, comments can't be done right.

                Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                N Offline
                N Offline
                Nelek
                wrote on last edited by
                #25

                Have you been reviewing your own code years later? At the beginning I was like you, but then I started having to upgrade my own code... I ended writing comments where needed note: I say where needed, not overall. But... if not sure, the default is... comment, better one too much than one too few.

                M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                Sander RosselS K 2 Replies Last reply
                0
                • Sander RosselS Sander Rossel

                  Customers do that :laugh: I have a similar story with a printer. The user pressed the print button to print somewhere around 100 to 150 invoices. It often happened that the printing stopped after 50 or so invoices. And always at the end of the day (because that's when they printed invoices). So I was testing my software, looking for bugs, writing "fixes" for "what could be it", added additional logging, everything, but I was never able to find the problem. And when I visited it didn't happen, of course. This went on for weeks. Then my manager visited them, for completely unrelated business, and called me "Is that print problem fixed already? I'm about to leave, but they're going to print invoices so I can check on them now." He checked and you'll never believe what their issue was. They clicked the print button and SHUT DOWN THEIR COMPUTER TO GO HOME!!! :wtf: :omg: :~ X| Never did it occur to them that shutting down the computer would stop it from printing. I can tell you I felt like driving a truck over their computers! :laugh:

                  Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                  D Offline
                  D Offline
                  DerekT P
                  wrote on last edited by
                  #26

                  My very first paid job was working with a mainframe at British Rail, in the 1970s. We used a TSO (Time Sharing System) and a few terminals in a dedicated room. I had a train to catch home so usually was one of the first to leave. Very often the next morning I'd find my colleagues scratching their heads - seems the mainframe had crashed the previous evening. This happened pretty much every day for a couple of weeks. Eventually I came in late one day (train delayed) and my boss had noticed my terminal was powered off. How or why turning off the terminal crashed the mainframe I never understood, but crash it it did. If only they'd told me, a keen young "Energy Studies" student eager to not waste electricity... At that job too we received mag.tape data, sent up from HQ in London. Usually it arrived fine, but on occasions all the data was wiped. This was at the Railway Technical Centre at Derby where all sorts of testing went on. Turns out the tapes came up, for convenience, on one of the test trains, right into the RTC, and on some days the coaches were shunted onto one of the tracks they were doing overhead power line testing... oops.

                  1 Reply Last reply
                  0
                  • D Daniel Pfeffer

                    See [Einstein's definition of insanity](https://www.brainyquote.com/quotes/quotes/a/alberteins133991.html).

                    If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                    P Offline
                    P Offline
                    PIEBALDconsult
                    wrote on last edited by
                    #27

                    Einstein never used a (modern) computer.

                    1 Reply Last reply
                    0
                    • N Nelek

                      Have you been reviewing your own code years later? At the beginning I was like you, but then I started having to upgrade my own code... I ended writing comments where needed note: I say where needed, not overall. But... if not sure, the default is... comment, better one too much than one too few.

                      M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                      Sander RosselS Offline
                      Sander RosselS Offline
                      Sander Rossel
                      wrote on last edited by
                      #28

                      Yes, I did. And I've always been able to follow it (and my memory concerning code is really bad, most of the time I can't even remember writing it, let alone what it does) :D Nothing you can say or do will make me change my mind on comments. They do more harm than good. I've written a little tip about comments some years ago: Write comments that matter[^] It shows that I'm not completely against comments, but use them sparse and wise :)

                      Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                      N 1 Reply Last reply
                      0
                      • S Super Lloyd

                        :laugh: :thumbsup: Really should be in a loop 42 times! 42 times always work out nicely! ;P

                        A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!

                        S Offline
                        S Offline
                        sx2008
                        wrote on last edited by
                        #29

                        Don't forget to put in an

                        Thread.Sleep(500)

                        to give the database connection a chance to recover from the failure state. ;P

                        1 Reply Last reply
                        0
                        • Sander RosselS Sander Rossel

                          Yes, I did. And I've always been able to follow it (and my memory concerning code is really bad, most of the time I can't even remember writing it, let alone what it does) :D Nothing you can say or do will make me change my mind on comments. They do more harm than good. I've written a little tip about comments some years ago: Write comments that matter[^] It shows that I'm not completely against comments, but use them sparse and wise :)

                          Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                          N Offline
                          N Offline
                          Nelek
                          wrote on last edited by
                          #30

                          Sander Rossel wrote:

                          Nothing you can say or do will make me change my mind on comments.

                          I am not trying to convince you. I am just giving another point of view related to your message.

                          Sander Rossel wrote:

                          And I've always been able to follow it

                          I forgot to say: I have been programming in AWL/LAD for PLCs a quite similar language to assembly. There is a bit more difficult make code "self explanatory" and sometimes the names for the variables are coming from electrical engineer / customer...

                          Sander Rossel wrote:

                          t shows that I'm not completely against comments, but use them sparse and wise

                          That's exactly the point. And I agree with you, obvious comments just make the program unnecessarily longer and uncomfortable to read

                          M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                          Sander RosselS 1 Reply Last reply
                          0
                          • N Nelek

                            Sander Rossel wrote:

                            Nothing you can say or do will make me change my mind on comments.

                            I am not trying to convince you. I am just giving another point of view related to your message.

                            Sander Rossel wrote:

                            And I've always been able to follow it

                            I forgot to say: I have been programming in AWL/LAD for PLCs a quite similar language to assembly. There is a bit more difficult make code "self explanatory" and sometimes the names for the variables are coming from electrical engineer / customer...

                            Sander Rossel wrote:

                            t shows that I'm not completely against comments, but use them sparse and wise

                            That's exactly the point. And I agree with you, obvious comments just make the program unnecessarily longer and uncomfortable to read

                            M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                            Sander RosselS Offline
                            Sander RosselS Offline
                            Sander Rossel
                            wrote on last edited by
                            #31

                            Nelek wrote:

                            AWL/LAD for PLCs a quite similar language to assembly

                            I'd comment the hell out of that! :laugh:

                            Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                            1 Reply Last reply
                            0
                            • N Nelek

                              Have you been reviewing your own code years later? At the beginning I was like you, but then I started having to upgrade my own code... I ended writing comments where needed note: I say where needed, not overall. But... if not sure, the default is... comment, better one too much than one too few.

                              M.D.V. ;) If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about? Help me to understand what I'm saying, and I'll explain it better to you Rating helpful answers is nice, but saying thanks can be even nicer.

                              K Offline
                              K Offline
                              kalberts
                              wrote on last edited by
                              #32

                              When students learn their first programming, and hopefully good programming habits, the big issue is learning the craft of programming, not the complexities of the problem solution they are set to program. So the problem solution is usually fairly simple, down to trivial. So simple that the code line says it all. The professor requires is to comment the code, but what should I write? Isn't it obvious, doesn't the code line tell? - that is common reaction from students. You don't need comments until the problem solution is getting more complex than you can handle in the first programming course (and second, and third). The problem is so simple that the code IS obvious, and students get into the habit of writing obvious information into the comments. When they later in life get into really huge and composite data structures, intricate execution logic and complex interfaces, they are not into the habit of identifying the non-obvious, only the obvious. When I teach people programming, I give them one rule regarding comments: Don't waste comments on what the code does, but on why it does it. Of course some students rephrased the "what" part, and I remarked: Sure, you said so in the code statement. Now tell me why you did it! - and usually, they were able to come up with a "why". That's what comments are for.

                              1 Reply Last reply
                              0
                              • G gjp1311

                                Beacause it will surely work a 100% the second time :-\

                                SqlCommand cmd = new SqlCommand(query,conn);
                                SqlDataReader reader = null;
                                try
                                {
                                reader = cmd.ExecuteReader();
                                }
                                catch(InvalidOperationException e)
                                {
                                cmd = new SqlCommand(query,conn);
                                reader = cmd.ExecuteReader();
                                }

                                abmvA Offline
                                abmvA Offline
                                abmv
                                wrote on last edited by
                                #33

                                Try try until you succeed !!!

                                Caveat Emptor. "Progress doesn't come from early risers – progress is made by lazy men looking for easier ways to do things." Lazarus Long

                                We are in the beginning of a mass extinction. - Greta Thunberg

                                1 Reply Last reply
                                0
                                • D Daniel Pfeffer

                                  See [Einstein's definition of insanity](https://www.brainyquote.com/quotes/quotes/a/alberteins133991.html).

                                  If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                                  R Offline
                                  R Offline
                                  Rob Grainger
                                  wrote on last edited by
                                  #34

                                  Two minor points here: 1. Einstein was a physicist, not a psychologist or psychiatrist. Being a genius in one field does not necessarily qualify you to speak with authority in any other. 2. He never said it anyway. At least he seems to have been smart enough to know (1). (Quora[^])

                                  "If you don't fail at least 90 percent of the time, you're not aiming high enough." Alan Kay.

                                  1 Reply Last reply
                                  0
                                  • Sander RosselS Sander Rossel

                                    Even though I consider comments to be one of the evils of programming I agree with you on this one :D

                                    Best, Sander arrgh.js - Bringing LINQ to JavaScript SQL Server for C# Developers Succinctly Object-Oriented Programming in C# Succinctly

                                    R Offline
                                    R Offline
                                    Rob Grainger
                                    wrote on last edited by
                                    #35

                                    It's my fundamental issue with Literate programming - Wikipedia[^], it assumes programmer's have basic literacy.

                                    "If you don't fail at least 90 percent of the time, you're not aiming high enough." Alan Kay.

                                    1 Reply Last reply
                                    0
                                    • D Daniel Wilianto

                                      True story. Some users seems to assume that printers have internal memory which would keep our queued documents. This assumption comes from a fact that printer keeps printing even when they closed our software. They don't know that these queued documents are stored on operating system's printer spooler service. Some colleagues once asked me, why did her printer stop printing? I who was in the middle of serious work mode, glanced over at her desk and yelled, you turned off your computer, that's why!

                                      R Offline
                                      R Offline
                                      Rob Grainger
                                      wrote on last edited by
                                      #36

                                      We have a networked printer that very much does have an internal queue, so different people may have had different experiences. (At first I found it unsettling, as jobs disappeared from the queue on my PC almost immediately every time).

                                      "If you don't fail at least 90 percent of the time, you're not aiming high enough." Alan Kay.

                                      1 Reply Last reply
                                      0
                                      • K kalberts

                                        If "try again!" always was silly coding practice, the the concept of "busy waiting" would not be known. Busy waiting does have its place, especially in embedded systems where the processor has nothing else to do. Another situation is where several activities are competing for the same resource, but they hold the resource comparatively briefly. As long as you can modify all the competitors, you could program the queueing mechanism, where a process trying to access a busy resource is sent to sleep in a queue and woken up when it gets its turn. Often you can only modify some of the competitors. The effort of implementing a queue mechanism may be high. If the risk of collision is small, it simply doesn't pay. I have fairly recently programmed a couple "try again" cases: On a quite heavily loaded file system, the number of exceptions due to confliciting accesses was higher than desired. So, when making modifications to a set of files, I make one try for each. Those failing are put into a list for retrying, and a second attempt is made once the first round was completed. Only after a second try, the user is notified. We went from too many access collisions to almost none. Sometimes, the second try came too fast, and the file was still busy. So I added a 5 ms sleep before starting a second round, and after that I haven't seen a single collision. This "try again" code is next to trivial, and it does solve a real problem. So I cannot agree that the strategy is silly in every case. Sometimes it makes perfect sense.

                                        R Offline
                                        R Offline
                                        Rob Grainger
                                        wrote on last edited by
                                        #37

                                        Member 7989122 wrote:

                                        I have fairly recently programmed a couple "try again" cases: On a quite heavily loaded file system, the number of exceptions due to confliciting accesses was higher than desired. So, when making modifications to a set of files, I make one try for each. Those failing are put into a list for retrying, and a second attempt is made once the first round was completed. Only after a second try, the user is notified. We went from too many access collisions to almost none. Sometimes, the second try came too fast, and the file was still busy. So I added a 5 ms sleep before starting a second round, and after that I haven't seen a single collision.

                                        So, you just assumed that whoever/whatever else had been writing to the file had been doing nothing worthwhile? Personally, if I detect any changes to a file I would avoid writing to it, and notify the user. Better still, open it for exclusive write.

                                        "If you don't fail at least 90 percent of the time, you're not aiming high enough." Alan Kay.

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups